Golang中的加密和解密:使用AES和RSA算法 随着互联网的不断发展,安全性越来越受到人们的关注。加密和解密成为了保护数据安全的重要手段之一。在Golang中,加密和解密可以使用AES和RSA算法来实现。本文将介绍Golang中如何使用AES和RSA算法进行加密和解密。 一、AES AES是一种高级加密标准,是一种对称加密算法。对称加密算法是指加密和解密所使用的密钥是相同的。使用AES算法进行加密和解密需要先生成一个密钥,然后使用该密钥进行加密和解密操作。 1.生成密钥 生成密钥可以使用crypto/rand包中的函数实现。下面是一个生成32位密钥的示例代码: ```go key := make([]byte, 32) if _, err := rand.Read(key); err != nil { log.Fatal(err) } ``` 2.加密 使用AES算法进行加密需要使用crypto/aes包中的函数实现。下面是一个使用AES算法进行加密的示例代码: ```go func aesEncrypt(plaintext []byte, key []byte) ([]byte, error) { block, err := aes.NewCipher(key) if err != nil { return nil, err } plaintext = PKCS5Padding(plaintext, block.BlockSize()) ciphertext := make([]byte, len(plaintext)) iv := make([]byte, aes.BlockSize) if _, err := rand.Read(iv); err != nil { return nil, err } mode := cipher.NewCBCEncrypter(block, iv) mode.CryptBlocks(ciphertext, plaintext) ciphertext = append(iv, ciphertext...) return ciphertext, nil } ``` 在上面的代码中,使用AES算法进行加密的关键步骤是: 1.创建AES加密器,使用密钥key作为参数。 2.对明文进行填充,使其长度为AES块大小的倍数。 3.生成一个随机的初始化向量iv。 4.创建CBC加密模式,使用加密器和初始化向量iv作为参数。 5.对明文进行加密,返回密文。 在加密过程中,需要注意的是,需要使用填充算法对明文进行填充,以保证明文长度是AES块大小的倍数。 3.解密 使用AES算法进行解密的过程与加密过程类似。下面是一个使用AES算法进行解密的示例代码: ```go func aesDecrypt(ciphertext []byte, key []byte) ([]byte, error) { block, err := aes.NewCipher(key) if err != nil { return nil, err } iv := ciphertext[:aes.BlockSize] ciphertext = ciphertext[aes.BlockSize:] mode := cipher.NewCBCDecrypter(block, iv) plaintext := make([]byte, len(ciphertext)) mode.CryptBlocks(plaintext, ciphertext) plaintext = PKCS5UnPadding(plaintext) return plaintext, nil } ``` 在上面的代码中,使用AES算法进行解密的关键步骤是: 1.创建AES解密器,使用密钥key作为参数。 2.从密文中获取初始化向量iv。 3.创建CBC解密模式,使用解密器和初始化向量iv作为参数。 4.对密文进行解密,返回明文。 在解密过程中,需要注意的是,需要使用填充算法对解密出来的明文进行去填充,以得到原始的明文。 二、RSA RSA是一种非对称加密算法。与对称加密算法不同,RSA算法加密和解密使用的密钥是不同的。RSA算法包括公钥和私钥两个密钥,公钥用于加密,私钥用于解密。 1.生成密钥对 生成RSA密钥对可以使用crypto/rsa包中的函数实现。下面是一个生成RSA密钥对的示例代码: ```go func generateRSAKey() (*rsa.PrivateKey, error) { bits := 2048 privateKey, err := rsa.GenerateKey(rand.Reader, bits) if err != nil { return nil, err } return privateKey, nil } ``` 在上面的代码中,使用2048位的RSA算法生成一个私钥。 2.加密 使用RSA算法进行加密需要使用crypto/rsa包中的函数实现。下面是一个使用RSA算法进行加密的示例代码: ```go func rsaEncrypt(plaintext []byte, publicKey *rsa.PublicKey) ([]byte, error) { ciphertext, err := rsa.EncryptPKCS1v15(rand.Reader, publicKey, plaintext) if err != nil { return nil, err } return ciphertext, nil } ``` 在上面的代码中,使用RSA算法进行加密的关键步骤是: 1.调用rsa.EncryptPKCS1v15函数进行加密,使用公钥publicKey作为参数。 2.对密文进行返回。 3.解密 使用RSA算法进行解密的过程与加密过程类似。下面是一个使用RSA算法进行解密的示例代码: ```go func rsaDecrypt(ciphertext []byte, privateKey *rsa.PrivateKey) ([]byte, error) { plaintext, err := rsa.DecryptPKCS1v15(rand.Reader, privateKey, ciphertext) if err != nil { return nil, err } return plaintext, nil } ``` 在上面的代码中,使用RSA算法进行解密的关键步骤是: 1.调用rsa.DecryptPKCS1v15函数进行解密,使用私钥privateKey作为参数。 2.对明文进行返回。 三、示例代码 下面是一个使用AES和RSA算法进行加密和解密的示例代码: ```go package main import ( "crypto/aes" "crypto/cipher" "crypto/rand" "crypto/rsa" "crypto/sha256" "crypto/x509" "encoding/base64" "encoding/pem" "fmt" "io/ioutil" "log" ) func main() { plaintext := "Hello, world!" fmt.Println("Plaintext:", plaintext) // AES加密 key := make([]byte, 32) if _, err := rand.Read(key); err != nil { log.Fatal(err) } ciphertext, err := aesEncrypt([]byte(plaintext), key) if err != nil { log.Fatal(err) } fmt.Println("AES key:", base64.StdEncoding.EncodeToString(key)) fmt.Println("AES ciphertext:", base64.StdEncoding.EncodeToString(ciphertext)) // RSA加密 publicKey, err := readRSAPublicKey("public.pem") if err != nil { log.Fatal(err) } encryptedKey, err := rsaEncrypt(key, publicKey) if err != nil { log.Fatal(err) } fmt.Println("RSA encrypted key:", base64.StdEncoding.EncodeToString(encryptedKey)) // RSA解密 privateKey, err := readRSAPrivateKey("private.pem") if err != nil { log.Fatal(err) } decryptedKey, err := rsaDecrypt(encryptedKey, privateKey) if err != nil { log.Fatal(err) } fmt.Println("RSA decrypted key:", base64.StdEncoding.EncodeToString(decryptedKey)) // AES解密 plaintext2, err := aesDecrypt(ciphertext, decryptedKey) if err != nil { log.Fatal(err) } fmt.Println("Plaintext2:", string(plaintext2)) } func aesEncrypt(plaintext []byte, key []byte) ([]byte, error) { block, err := aes.NewCipher(key) if err != nil { return nil, err } plaintext = PKCS5Padding(plaintext, block.BlockSize()) ciphertext := make([]byte, len(plaintext)) iv := make([]byte, aes.BlockSize) if _, err := rand.Read(iv); err != nil { return nil, err } mode := cipher.NewCBCEncrypter(block, iv) mode.CryptBlocks(ciphertext, plaintext) ciphertext = append(iv, ciphertext...) return ciphertext, nil } func aesDecrypt(ciphertext []byte, key []byte) ([]byte, error) { block, err := aes.NewCipher(key) if err != nil { return nil, err } iv := ciphertext[:aes.BlockSize] ciphertext = ciphertext[aes.BlockSize:] mode := cipher.NewCBCDecrypter(block, iv) plaintext := make([]byte, len(ciphertext)) mode.CryptBlocks(plaintext, ciphertext) plaintext = PKCS5UnPadding(plaintext) return plaintext, nil } func PKCS5Padding(src []byte, blockSize int) []byte { padding := blockSize - len(src)%blockSize padtext := bytes.Repeat([]byte{byte(padding)}, padding) return append(src, padtext...) } func PKCS5UnPadding(src []byte) []byte { length := len(src) unpadding := int(src[length-1]) return src[:(length - unpadding)] } func readRSAPrivateKey(filename string) (*rsa.PrivateKey, error) { privateKeyBytes, err := ioutil.ReadFile(filename) if err != nil { return nil, err } privateKeyBlock, _ := pem.Decode(privateKeyBytes) privateKey, err := x509.ParsePKCS1PrivateKey(privateKeyBlock.Bytes) if err != nil { return nil, err } return privateKey, nil } func readRSAPublicKey(filename string) (*rsa.PublicKey, error) { publicKeyBytes, err := ioutil.ReadFile(filename) if err != nil { return nil, err } publicKeyBlock, _ := pem.Decode(publicKeyBytes) publicKey, err := x509.ParsePKCS1PublicKey(publicKeyBlock.Bytes) if err != nil { return nil, err } return publicKey, nil } ``` 在上面的代码中,首先使用AES算法对明文进行加密,然后使用RSA算法对密钥进行加密,最后把加密后的密钥和密文一起传输到对方。对方先使用RSA算法对密钥进行解密,然后再使用AES算法对密文进行解密,从而得到原始的明文。