Asymmetric encryption algorithm

1. Disadvantages of symmetric encryption

  • Key distribution difficulty

  • Distribution of the secret key can be accomplished through asymmetric encryption

    Alice and Bob communicate, and Alice sends data to Bob using a symmetric encryption process

    1.Bob generates an asymmetric key pair,

    2.Bob sends the public key to Alice

    3.Alice generates a secret key for symmetric encryption

    4.Alice uses Bob’s public key to encrypt the symmetrically encrypted secret key and sends it to Bob

    5.Bob uses the private key to decrypt data and obtain the symmetric encryption private key

    The two sides of the communication encrypt the data symmetrically using the written secret key

  • Scenario analysis

1. Information encryption (user A writes data to user B, and user B only reads information) A: public key B: private key

2. Login authentication (A client logs in to the server, connects to the server, and requests personal data from the server.) Client: private key Server: public key

3. Digital signature (indicates that the information is not tampered and is indeed sent by the information owner and is attached to the end of the original message) Sender: private key Receiver: public key

4. E-banking U Shield Personal: private key Bank: public key

Bottom line: Whoever is more important to the data takes the private key

2. Asymmetrically encrypted secret keys

  • There is no difficult problem of key distribution

3. Generate an RSA key pair

  1. Concepts X509 certificate specification, PEM, base64
  • Pem is an encoding specification derived from the Confidentiality enhanced mail protocol for data encryption
  • Base64 is also an encoding specification and the process is reversible
    • Replace the original data with 64 characters (A-z, a-z, 0-9, /, +), regardless of the original data.

Asn.1 Abstract syntax marks the PKCS1 standard

  1. Key pair generation process

The private key is generated

Func GenerateKey(random IO.Reader, bits int) (Priv *PrivateKey, err Error)

  • rand.Reader -> import “crypto/rand”
  • Bits An integer multiple of 1024 – Recommended

2. Use x509 to serialize the obtained rsa PrivateKey as asn.1’s DER encoding string func MarshalPKCS1PrivateKey(key * rsa.privatekey) []byte

3. Initialize a PEM. Block by setting the private key string to the PEM format Block

Func Encode(out IO.Writer, B *Block) error out – Prepare a file pointer

Public key generation

1. Obtain the public key information from the obtained private key object

Type PrivateKey struct {PublicKey // PublicKey D * big.int // private index Primes []* big.int // N Can speed up the operation of private keys in some cases Precomputed PrecomputedValues}Copy the code

2. Use x509 to serialize the obtained RSA public key into a string

func MarshalPKIXPublicKey(pub interface{}) ([]byte, error)
Copy the code

3. Set the public key string to pem format

4. Use pem to encode the configured data and write it to a disk file

4. The RSA encryption

package main

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

// Generate rsa private and public keys and write them to disk files
func GenerateRsaKey(keySize int) {
	1. Generate an RSA key
	privateKey, err := rsa.GenerateKey(rand.Reader, keySize)
	iferr ! =nil {
		panic(err)
	}
	//2. Use x509 to serialize the obtained RSA private key to asN.1's DER encoding string
	derText := x509.MarshalPKCS1PrivateKey(privateKey)
	//3. Create a pem.Block structure
	block := pem.Block{
		Type: "rsa private key",
		Bytes: derText,
	}
	//4. Use pem to encode the configured private key data and write it to a disk file
	file, err := os.Create("private.pem")
	iferr ! =nil {
		panic(err)
	}
	err = pem.Encode(file, &block)
	iferr ! =nil {
		panic(err)
	}

	// ========== public key ==================
	1. Obtain the public key from the private key
	publicKey := privateKey.PublicKey
	//2. Use x509 to serialize the public key into a string
	marshalPKIXPublicKey, err := x509.MarshalPKIXPublicKey(&publicKey)
	iferr ! =nil {
		panic(err)
	}
	//3. Enter the public key string into the PEM format block
	block = pem.Block{
		Type:    "rsa public key",
		Headers: nil,
		Bytes:   marshalPKIXPublicKey,
	}
	/ / 4. Pem coding
	file, err = os.Create("public.pem")
	iferr ! =nil {
		panic(err)
	}
	err = pem.Encode(file, &block)
	iferr ! =nil {
		panic(err)
	}
	file.Close()
}

/ / rsa encryption
func RSAEncrypt(plainText []byte, fileName string) []byte {
	//1. Open the public key file
	file, err := os.Open(fileName)
	iferr ! =nil {
		panic(err)
	}
	fileInfo, err := file.Stat()
	iferr ! =nil {
		panic(err)
	}
	buf := make([]byte, fileInfo.Size())
	_, err = file.Read(buf)
	iferr ! =nil {
		panic(err)
	}
	file.Close()
	//2.pem decode
	block, _ := pem.Decode(buf)
	publicKey, err := x509.ParsePKIXPublicKey(block.Bytes)
	iferr ! =nil {
		panic(err)
	}
	pubKey := publicKey.(*rsa.PublicKey)
	//3. Use public key encryption
	cipherText, err := rsa.EncryptPKCS1v15(rand.Reader, pubKey, plainText)
	iferr ! =nil {
		panic(err)
	}
	return cipherText
}

/ / rsa decryption
func RSADecrypt(cipherText []byte, fileName string) []byte {
	1. Open the private key file
	file, err := os.Open(fileName)
	iferr ! =nil {
		panic(err)
	}
	fileInfo, err := file.Stat()
	iferr ! =nil {
		panic(err)
	}
	buf := make([]byte, fileInfo.Size())
	_, err = file.Read(buf)
	iferr ! =nil {
		panic(err)
	}
	//2.pem decode
	block, _ := pem.Decode(buf)
	privateKey, err := x509.ParsePKCS1PrivateKey(block.Bytes)
	iferr ! =nil {
		panic(err)
	}
	//3. Decrypt data
	plainText, err := rsa.DecryptPKCS1v15(rand.Reader, privateKey, cipherText)
	iferr ! =nil {
		panic(err)
	}
	return plainText
}

func main(a) {
	GenerateRsaKey(1024)
	src := []byte("Solved the difficult problem of secret key distribution, can not encrypt slightly longer data, mainly used to encrypt symmetric secret keys.")
	cipherText := RSAEncrypt(src, "public.pem")
	plainText := RSADecrypt(cipherText, "private.pem")
	fmt.Println("Decryption result:".string(plainText))
}
Copy the code