• 1. Introduction to cryptography
  • 2. Symmetric encryption
  • 3. Packet encryption mode
  • 4. Asymmetric encryption
  • 5. One-way hash functions
  • 6. Message authentication code
  • 7. Digital signature
  • Certificate of 8.
  • 9.SSL/TLS
Asymmetric encryption is also called public key cryptography: Encrypt with a public key and decrypt with a private key.Copy the code

In symmetric ciphers, because the encryption and decryption keys are the same, the key must be distributed to the recipient. The key used for decryption must be distributed to the recipient, which is called the key distribution problem. If asymmetric encryption is used, which can also be called public key cryptography, there is no need to distribute the key for decryption to the recipient, thus solving the key distribution problem. Asymmetric encryption is arguably the greatest invention in the history of cryptography.

In asymmetric encryption, keys are classified into encryption keys and decryption keys. The sender uses the encryption key to encrypt the message, and the receiver uses the decryption key to decrypt the ciphertext. To understand public key ciphers, it is important to make a clear distinction between encryption and decryption keys. The encryption key is used by the sender for encryption, and the decryption key is used by the receiver for decryption.

If we think about the difference between encryption keys and decryption keys, we can find:

  • The sender only needs the encryption key
  • The recipient only needs to decrypt the key
  • The decryption key cannot be obtained by an eavesdropper
  • Encryption keys can also be accessed by an eavesdropper

In other words, the decryption key is kept by the receiver from the beginning, so the key delivery problem can be solved by simply sending the encryption key to the sender, without the need to deliver the decryption key at all.

In asymmetric encryption, the encryption key is generally public. Because an encryption key can be disclosed arbitrarily, it is called a publickey. The public key could be sent directly to the recipient in the mail, placed in a newspaper AD column, placed on the street as a billboard, or made available to anyone in the world on a web page without fear of eavesdropping.

Of course, we don’t have to make the public key public to everyone in the world, but we do need to at least send it to those who need to use it for encryption (that is, to the sender of the ciphertext themselves).

The decryption key, by contrast, is never made public; it can only be used by you, hence it is called a privatekey. The private key cannot be known to others, nor can it be sent to others, nor even to one’s own communication object.

The public key and private key correspond to each other. A pair of public and private keys is called a keypair. Ciphertext encrypted by a public key can be decrypted only by using the private key paired with the public key. The two keys in a key pair have a very close relationship (mathematically) — so the public and private keys cannot be generated separately.

The user of a public key password needs to generate a key pair that includes a public key and a private key, in which the public key is sent to others and the private key is used only by himself. We will try to generate a key pair in detail later.

4.1 Asymmetric encrypted Communication flow

Let’s take a look at the communication flow using public key cryptography. As before, let’s assume Alice is sending a message to Bob, Alice is the sender and Bob is the receiver, and this time Eve is able to steal their communication.

In public asymmetric encrypted communication, the communication process is initiated by the receiver Bob.

  1. Bob generates a key pair containing public and private keys.

    The private key is kept by Bob for safekeeping.

  2. Bob sends Alicea his public key

    It doesn’t matter if Bob’s public key is intercepted by Eve.

    Sending the public key to Alice means that Bob asks Alice to encrypt the message with the public key and send it to him.

  3. Alice uses Bob’s public key to encrypt the message.

    The encrypted message can only be decrypted using Bob’s private key.

    Although Alice has Bob’s public key, the ciphertext cannot be decrypted with Bob’s public key.

  4. Alice sends the ciphertext to Bobo

    It doesn’t matter if the ciphertext is intercepted by Eve. Eve may have Bob’s public key, but it cannot be decrypted using Bob’s public key.

  5. Bob decrypts the ciphertext with his private key.

    Take a look at the following figure to see what information is transmitted between Alice and Bob. There are only two pieces of information transmitted between them: Bob’s public key and the ciphertext encrypted with Bob’s public key. Since Bob’s private key does not appear in the contents of the communication, Eve, the eavesdropper, cannot decrypt the ciphertext.

Eve, the eavesdropper, may have Bob’s public key, but Bob’s public key is only the encryption key, not the decryption key, so Eve, the eavesdropper, cannot complete the decryption operation.

4.2 RSA

Asymmetric encryption is divided into encryption keys and decryption keys, but how exactly is this done? In this section we will explain the most widely used public key cryptography algorithm – RSA.

RSA is an asymmetric encryption algorithm whose name is derived from the first letters of the last names of its three developers, RonRivest, AdiShamir, and LeonardAdleman.

RSA can be used for asymmetric encryption and for digital signatures, which we’ll cover in a later section.

In 1983, RSA patented the RSA algorithm in the United States, but the patent has now expired.

2 RSA encryption

Now we can finally talk about the asymmetric encryption representative – RSA encryption process. In RSA, the plaintext, key, and ciphertext are all numbers. The RSA encryption process can be expressed in the following formula, as follows.


cipher = Ming wen E m o d N ( R S A Encryption) Ciphertext = plaintext ^ E mod N (RSA encryption)

That is, the ciphertext of RSA is the result of the modN of the number representing the plaintext raised to the E power. In other words, multiply the plain text by itself E times, and then divide the result by N for the remainder, which is ciphertext.

Gee, is it that simple?

Yeah, it’s that simple. Just power the plaintext and mod, that’s the whole encryption process. Unlike symmetric ciphers, where there are a lot of complicated functions and operations that move bits around like scrambled eggs and require XOR operations, RSA is very simple.

By the way, what are the two numbers in the encryption formula — one, one, E, and N? RSA encryption is the plaintext E power modN, so as long as the two numbers E and N, anyone can complete the encryption operation. Therefore, E and N are RSA encryption keys, that is, the combination of E and N is the public key.

However, E and N are not just any numbers, they are calculated carefully. By the way, E is the first letter of Encryption and N is the first letter of Number.

One of the most misleading things to note is that the numbers E and N are not key pairs. Only the numbers E and N form a public key, so we usually write them in the form “the public key is (E, N)” or “the public key is {E, N}”, enclosing E and N in parentheses.

Now that you know that RSA encryption == is “take the power of E modN”==, let’s look at RSA decryption.

4.2.2 RSA decryption

RSA decryption is as simple as encryption and can be expressed in the following formula:


clear = The secret wen D m o d N ( R S A Decryption) Plaintext = Ciphertext ^DmodN (RSA Decryption)

In other words, the plaintext can be obtained by taking the modN of the number representing the ciphertext to the d-power. In other words, multiply the ciphertext itself D times and divide the result by N to get the remainder.

The number N used here is the same as the number N used for encryption. The numbers D and N together are the RSA decryption key, so the combination of D and N is the private key. Only those who know the numbers D and N can perform the decryption operation.

You should have noticed that in RSA, encryption and decryption take the same form. Encryption is “modN to the power E”, decryption is “modN to the power D”, which is really nice.

Of course, D is not just any number. As a decryption key, D is closely related to the number E. Otherwise, the result encrypted with E can be decrypted with D, such a mechanism is not possible.

Incidentally, D is the first letter of < Decryption, and N is the first letter of Number.

Let’s sort out what we have said above, as shown in the following table.

**RSA encryption and decryption **Copy the code

Generate public and private keys in 4.2.3 Go

Packages to import

import (
	"crypto/rsa"
	"crypto/rand"
	"crypto/x509"
	"encoding/pem"
	"os"
)
Copy the code

Process for generating a private key

  1. Use the GenerateKey method in RSA to generate the private key
  2. The resulting RAS private key is serialized as an ASN.1 DER encoded string using the X509 standard
  3. Sets the private key string to a PEM format block
  4. Encodes the set data using PEM and writes it to a disk file

Process for generating a public key

  1. Retrieves public key information from the resulting private key object
  2. The resulting RSA public key is serialized as a string using the X509 standard
  3. Sets the public key string to a PEM format block
  4. Encodes the set data through PEM and writes it to a disk file

Generate public and private key source code

Bits: Specifies the length of the generated key, in bits
func RsaGenKey(bits int) error{
	1. Generate a private key file
	// The GenerateKey function uses the random data generator to generate a pair of RSA keys with a specified number of words
	// Argument 1: Reader is a global, shared password with a strong random number generator
	// Parameter 2: the number of bits in the key
	privateKey, err := rsa.GenerateKey(rand.Reader, bits)
	iferr ! =nil{
		return err
	}
	MarshalPKCS1PrivateKey serializes the rsa private key into asn.1 PKCS#1 DER encoding
	derStream := x509.MarshalPKCS1PrivateKey(privateKey)
	// 3. Block represents the structure of the PEM encoding, which is set
	block := pem.Block{
		Type: "RSA PRIVATE KEY".//"RSA PRIVATE KEY",
		Bytes: derStream,
	}
	// 4. Create file
	privFile, err := os.Create("private.pem")
	iferr ! =nil{
		return err
	}
	// 5. Use pem encoding and write data to the file
	err = pem.Encode(privFile, &block)
	iferr ! =nil{
		return err
	}
	// 6. Close the file at the end
	defer privFile.Close()

	// 7. Generate the public key file
	publicKey := privateKey.PublicKey
	derPkix, err := x509.MarshalPKIXPublicKey(&publicKey)
	iferr ! =nil{
		return err
	}
	block = pem.Block{
		Type: "RSA PUBLIC KEY".//"PUBLIC KEY",
		Bytes: derPkix,
	}
	pubFile, err := os.Create("public.pem")
	iferr ! =nil{
		return err
	}
	// 8. Encode the public key and write to the file
	err = pem.Encode(pubFile, &block)
	iferr ! =nil{
		panic(err)
		return err
	}
	defer pubFile.Close()

	return nil

}
Copy the code

Important functions:

  1. The GenerateKey function uses random, a random data generator, to generate a pair of RSA keys with a specified number of words.

    "crypto/rsa"Functions in packagesfunc GenerateKey(random io.Reader, bits int) (priv *PrivateKey, err error)- parameters1Reader -- The RAND package implements a more secure random number generator for encryption and decryption. --varReader IO.Reader (rand package variable) - parameter2: bits: key length - Returned value1: indicates an RSA private key. - the return value2: Error messageCopy the code
  2. Serialize the rsa private key to asn.1 PKCS#1 DER encoding through x509

    "crypto/x509"Functions in packages (x509 packages parse X509.Encoded certificates and keys).func MarshalPKCS1PrivateKey(key *rsa.PrivateKey) []byte- parameters1: Private key obtained through rsa.GenerateKey - Returned value: Pass the private key through ASN1.The resulting private key encodes data after serializationCopy the code
  3. Set the Pem code structure

    Block represents the structure of the PEM encoding.type Block struct {
        Type    string            // Derived from the type of preface (e.g. "RSA PRIVATE KEY")
        Headers map[string]string // Optional header, Headers is a nullable multi-line key value pair.
        Bytes   []byte            // The decoded data is usually the ASN.1 structure encoded by DER
    }
    Copy the code
  4. The obtained private key in Pem format is written to disk through the file pointer

    "encoding/pem"Functions in packagesfunc Encode(out io.Writer, b *Block) error- parameters1: IO object that can be used for write operations. A file pointer - parameter must be specified2: A Pem Block object that is initializedCopy the code
  5. Obtain the public key from the RSA private key

    / / the private key
    type PrivateKey struct {
        PublicKey            / / the public key
        D         *big.Int   // Private index
        Primes    []*big.Int There are at least two prime factors of N
        // Contains pre-calculated values to speed up the operation of the private key under certain circumstances
        Precomputed PrecomputedValues
    }
    / / the public key
    type PublicKey struct {
        N   *big.Int / / die
        E   int      // Open index} use the privateKey to obtain the publicKey publicKey := privatekey. publicKey// privateKey is a privateKey object
    Copy the code
  6. The public key is serialized into PKIX format DER encoding through X509.

    "crypto/x509"Functions in packagesfunc MarshalPKIXPublicKey(pub interface{}) ([]byte, error)- parameters1: Public key obtained from the private key object - return value1: Passes the public key through the ASN1.Encoded data after serialization - return value2: Error messageCopy the code
  7. Format the data encoded by the public key into a Pem structure. For details, see the operation of the private key

  8. The obtained public key in Pem format is written to disk through the file pointer

  9. Generated private key and public key file data

    Private key file data
    -----BEGIN RSA PRIVATE KEY-----
    MIICXgIBAAKBgQC5bm0DCEV+EFeiLUqSshziqhSB30jXy5BWbPV5SlMq4aWiEknM
    i+Mw1aXic4bEsM3YyT73eWsifqZNSc/4fRaV4qz5OL8IIe9AZoGDSLX/Ar9AQMJf
    OHbAtdIlCGQ4d80KjpDpPs2wZkTqllWCg31d7U3DVEm5kqTGtSYIu9e7JQIDAQAB
    AoGARGdn72ZtvENrEHiEufjajwMO7Zng1TpS1I79PvEcHQWAhHkaoEo6VRl7SD41
    yPkv9njGsaQo0WDHGFvSTGhYm/EWGrBWRPc5xXbSBg7ty9Iza9B1ekAj8VfWryen
    Wje3xDOCVCDUiCcYdaSfPiJPYuWMSnNMNa+0cR921zBQg0ECQQDpCMljuH7LrpbC
    NDF5q+LbUWMAE2KLDPX4WmDSdZdIO3mPux3MdwOUEfrcvSBGZNB7gyaEG7goZL8G
    BqL22MJHAkEAy7SqbVPoPbMPHuLI52VQ2FDp6xxSWLhjmv1ePCHGo28MDCaHeVzZ
    QaxyuIbnY8A6NHfu/QGwz/eB941IjYNBMwJBAI9XEEl+mr++zIz4fdZRnGE7VqId
    SmgtuL7jGNtb6YpMyyFV/6ZdLp5N0PkmfEvQh0zyBycLxeNS1Q1n16Xu/tECQQCZ
    dF42wdDgOfWYFMu31VETw9CTtuApya3vYhMNRXx4Pf1bYeMIf/OCT8CUVbwWHwc5
    42d73TwvTorvy9TuFgSVAkEA6F69THlTn5oIP8IWHcHuqS01fIR/vGfEwQ4cFZGR ketfieyeeF8rjn4qzwT/ugwRNjkhfKmoILnIC8UhEEJdjA== -----END  RSA PRIVATE KEY-----Copy the code
    Public key file data
    -----BEGIN RSA PUBLIC KEY-----
    MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC5bm0DCEV+EFeiLUqSshziqhSB
    30jXy5BWbPV5SlMq4aWiEknMi+Mw1aXic4bEsM3YyT73eWsifqZNSc/4fRaV4qz5
    OL8IIe9AZoGDSLX/Ar9AQMJfOHbAtdIlCGQ4d80KjpDpPs2wZkTqllWCg31d7U3D
    VEm5kqTGtSYIu9e7JQIDAQAB
    -----END RSA PUBLIC KEY-----
    Copy the code

4.2.4 Using RSA in Go

  1. steps

    • Public key encryption

      1. Read out the public key from the public key file to get a pem encoded string
      2. Decodes the resulting string
      3. Use X509 to parse out the encoded public key
      4. The obtained public key is used to encrypt data through RSA
    • Private key to decrypt the

      1. Read out the private key in the private key file to obtain a pem encoded string
      2. Decodes the resulting string
      3. Use X509 to parse the encoded private key
      4. The obtained private key is used for data decryption through RSA
  2. Code implementation

    • RSA Public Key Encryption

      func RSAEncrypt(src, filename []byte) []byte {
          // 1. Read the contents of the file according to the name of the file
          file, err := os.Open(string(filename))
          iferr ! =nil {
              return nil
          }
          // 2. Read files
          info, _ := file.Stat()
          allText := make([]byte, info.Size())
          file.Read(allText)
          // close the file
          file.Close()
      
          // 4. Find the next block in PEM format from the data
          block, _ := pem.Decode(allText)
          if block == nil {
              return nil
          }
          // 5. Parse a public key encoded by DER
          pubInterface, err := x509.ParsePKIXPublicKey(block.Bytes)
          iferr ! =nil {
              return nil
          }
          pubKey := pubInterface.(*rsa.PublicKey)
      
          Public key encryption
          result, _ := rsa.EncryptPKCS1v15(rand.Reader, pubKey, src)
          return result
      }
      Copy the code
    • Decrypt the RSA private key

      func RSADecrypt(src, filename []byte) []byte {
        // 1. Read the contents of the file according to the name of the file
        file, err := os.Open(string(filename))
        iferr ! =nil {
            return nil
        }
        // 2. Read files
        info, _ := file.Stat()
        allText := make([]byte, info.Size())
        file.Read(allText)
        // close the file
        file.Close()
        // 4. Find the next block in PEM format from the data
        block, _ := pem.Decode(allText)
        Parse a private key in PEM format
        privateKey , err := x509.ParsePKCS1PrivateKey(block.Bytes)
        // 6. Decrypt private key
        result, _ := rsa.DecryptPKCS1v15(rand.Reader, privateKey, src)
      
          return result
        }
      Copy the code
    • Important function introduction

      1. The obtained private key in Pem format is written to disk through the file pointer

        "encoding/pem"Functions in packagesfunc Decode(data []byte) (p *Block, rest []byte)- Parameter data: data block to be parsed - Return value1: block in PEM format parsed from the argument - return value2: parameter data Indicates the remaining undecoded dataCopy the code
      2. Parse an DER encoded public key. The data in the Block structure of pem is asN.1 encoded

        The package to which the function belongs:"crypto/x509"
        func ParsePKIXPublicKey(derBytes []byte) (pub interface{}, err error)- derBytes: ASN taken from the Block structure of the PEM1.Encoded data - Returned value pub: indicates the interface object, which is actually public key data. - Parameter err: indicates an error messageCopy the code
      3. Parse an DER encoded private key. The data in the Block structure of pem is asN.1 encoded

        The package to which the function belongs:"crypto/x509"
        func ParsePKCS1PrivateKey(der []byte) (key *rsa.PrivateKey, err error)- der: indicates the ASN taken from the pem Block structure1.Encoded data - Returned value Key: parsed private key - Returned value err: error messageCopy the code
      4. Converts the interface to a public key

        PubKey := pubInterface.(* rsa.publickey) -pubInterface: ParsePKIXPublicKey function returnsinterface{} object -pubinterface.(* rsa.publickey): converts pubInterface to the PublicKey type rsa.publickeyCopy the code
      5. Encrypts data using public keys

        The package to which the function belongs:"crypto/rsa"
        func EncryptPKCS1v15(rand io.Reader, pub *PublicKey, msg []byte) (out []byte, err error)- Parameter rand: random number generator, and the value is rand.Reader - parameter pub: public key used for asymmetric encryption - parameter MSG: original data to be encrypted using the public key - Returned value out: data after encryption - Returned value err: error messageCopy the code
      6. Decrypt data using a private key

        The package to which the function belongs:"crypto/rsa"
        func DecryptPKCS1v15(rand io.Reader, priv *PrivateKey, ciphertext []byte) (out []byte, err error)- Parameter rand: random number generator, assigned to rand.Reader - Parameter priv: private key used for asymmetric encryption and decryption - Parameter cipherText: data to be decrypted using the private key - Returned value out: data obtained after decryption - Returned value err: The wrong letterCopy the code

4.3 ECC elliptic curve

  1. concept

    Elliptic Curve Cryptography (ECC), an algorithm for establishing public-key encryption, based on Elliptic curve mathematics. The use of elliptic curves in cryptography was independently proposed by Neal Koblitz and Victor Miller in 1985.

    The main advantage of ECC is that in some cases it uses smaller keys than other methods – such as the RSA encryption algorithm – to provide a comparable or higher level of security.

    Many forms of elliptic curve cryptography are slightly different, all of which rely on the widely acknowledged difficulty of solving the discrete logarithm problem of elliptic curves. Different from traditional encryption methods based on the difficulty of large prime factorization, ECC generates the key through the properties of elliptic curve equations.

    The ECC 164-bit key generates a level of security equivalent to that provided by RSA 1024-bit key, with less computation, faster processing, and less storage space and transmission bandwidth. At present, China’s second-generation ID cards are using 256-bit elliptic curve passwords, and the virtual currency Bitcoin also chooses ECC as its encryption algorithm.

    Specific algorithm for detailed reference:

    • www.cnblogs.com/Kalafinaian…

    • Blog.csdn.net/taifei/arti…

  2. Mathematical principles

    Public key encryption algorithms, whether RSA or ECC or others, rely on mathematical problems that are easy to compute forward (polynomial time complexity) and difficult to compute backward (exponential time complexity).

    The mathematical difficulties of elliptic curve dependence are:

    K is a positive integer, P is the point on the elliptic curve (called the base point), k*P=Q, given Q and P, it is difficult to calculate k

4.4 Asymmetric encryption solution

  • Is asymmetric encryption more confidential than symmetric encryption?

    This question is unanswerable because the level of secrecy varies according to the length of the key

  • Is it more secure to use asymmetric encryption with 1024bit secret key length versus symmetric encryption with 128bit secret key length?

    It isn’t.

    The key length of asymmetric encryption cannot be directly compared with that of symmetric encryption. The table below (from Applied Cryptography) shows that a 1024 bit public key cipher is more resistant to brute force than a 128-bit symmetric cipher.

    Symmetric encryption key length Asymmetric encryption key length
    128 bits 2304 bits
    112 bits 1792 bits
    80 bits 768 bits
    64 bits 512 bits
    56 bits 384 bits
  • With asymmetric encryption, will symmetric encryption be replaced in the future?

    Don’t.

    In general, asymmetric encryption is only a few hundredths of the speed of symmetric encryption with the same secret key length. Therefore, asymmetric encryption is not suitable for encrypting very long message contents. Depending on the purpose, symmetric and asymmetric encryption may also be used together, for example, a hybrid cryptosystem is a combination of the two ciphers.