Go语言中提供了多种加密、解密算法,本文介绍其中的两种:AES和RSA。
一、AES加密解密
AES是一种对称加密算法,即加密和解密使用同一把密钥。Go语言中提供了crypto/aes包来实现AES加密解密。
- AES加密
AES加密需要指定密钥和明文,将明文转换为字节数组,再使用AES加密算法对字节数组进行加密,最后将密文转换为base64字符串输出。
示例代码:
package main
import (
"crypto/aes"
"crypto/cipher"
"encoding/base64"
"fmt"
)
func AESEncrypt(origData, key []byte) (string, error) {
// 创建加密算法实例
block, err := aes.NewCipher(key)
if err != nil {
return "", err
}
// 补全明文
blockSize := block.BlockSize()
origData = PKCS5Padding(origData, blockSize)
// 创建CBC模式加密实例
iv := key[:blockSize]
blockMode := cipher.NewCBCEncrypter(block, iv)
// 加密
encrypted := make([]byte, len(origData))
blockMode.CryptBlocks(encrypted, origData)
// 转为base64字符串
return base64.StdEncoding.EncodeToString(encrypted), nil
}
// PKCS5Padding 补全明文
func PKCS5Padding(ciphertext []byte, blockSize int) []byte {
padding := blockSize - len(ciphertext)%blockSize
padtext := bytes.Repeat([]byte{byte(padding)}, padding)
return append(ciphertext, padtext...)
}
func main() {
key := []byte("0123456789abcdef")
data := []byte("hello world")
encrypted, err := AESEncrypt(data, key)
if err != nil {
fmt.Println(err)
return
}
fmt.Println("encrypted:", encrypted)
}
- AES解密
AES解密需要指定密钥和密文,将密文转换为字节数组,再使用AES解密算法对字节数组进行解密,最后去掉填充的字节即可得到明文。
示例代码:
package main
import (
"crypto/aes"
"crypto/cipher"
"encoding/base64"
"fmt"
)
func AESDecrypt(encrypted string, key []byte) ([]byte, error) {
// 创建解密算法实例
block, err := aes.NewCipher(key)
if err != nil {
return nil, err
}
// 解密base64字符串
encryptedData, err := base64.StdEncoding.DecodeString(encrypted)
if err != nil {
return nil, err
}
// 创建CBC模式解密实例
blockSize := block.BlockSize()
iv := key[:blockSize]
blockMode := cipher.NewCBCDecrypter(block, iv)
// 解密
decrypted := make([]byte, len(encryptedData))
blockMode.CryptBlocks(decrypted, encryptedData)
// 去掉填充的字节
return PKCS5UnPadding(decrypted), nil
}
// PKCS5UnPadding 去掉填充的字节
func PKCS5UnPadding(origData []byte) []byte {
length := len(origData)
unpadding := int(origData[length-1])
return origData[:(length - unpadding)]
}
func main() {
key := []byte("0123456789abcdef")
encrypted := "8zI4oMw0fcoCv5a5W8fX9Q=="
decrypted, err := AESDecrypt(encrypted, key)
if err != nil {
fmt.Println(err)
return
}
fmt.Println("decrypted:", string(decrypted))
}
二、RSA加密解密
RSA是一种非对称加密算法,即加密和解密使用不同的密钥(公钥和私钥)。Go语言中提供了crypto/rsa包来实现RSA加密解密。
- RSA加密
RSA加密需要指定公钥和明文,将明文转换为字节数组,再使用RSA公钥加密算法对字节数组进行加密,最后将密文转换为base64字符串输出。
示例代码:
package main
import (
"crypto/rand"
"crypto/rsa"
"crypto/x509"
"encoding/base64"
"fmt"
)
func RSAEncrypt(origData []byte, publicKey []byte) (string, error) {
// 解析公钥
block, _ := pem.Decode(publicKey)
if block == nil {
return "", fmt.Errorf("failed to decode public key")
}
pub, err := x509.ParsePKIXPublicKey(block.Bytes)
if err != nil {
return "", err
}
// 加密
encrypted, err := rsa.EncryptPKCS1v15(rand.Reader, pub.(*rsa.PublicKey), origData)
if err != nil {
return "", err
}
// 转为base64字符串
return base64.StdEncoding.EncodeToString(encrypted), nil
}
func main() {
publicKey := []byte(`
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA1xOZlQJ6NnUg+RYd6JHg
wq3Pq+g8/9F1M9Z6Ezr1rTm7YyBb+eJwVvB+gJk7VX9Q2ZBhVvSf0Yt8zIc2Qw0f
4LHz4JW8M+9XZKxJkq3zBpW8YjKzJ5+eDvQJQgW8F5GKj5I5EeSv+8bYt2BmGw1S
4m4n8eJWgZL9dZKp3PvqzY5W5J76dNwJf2QvM8is5W5j5LZP5/6KvJ6RlU6JcUwO
yJL3q8HkWb1X9+VHxT1rAP7hTtT+uJ0VzJ0sZs7VJfQs+9JI1ZM1hLrYzYj+TzwE
wJGn6mJj7oDQ2sX1Zn0z6Uv1Rn/0dUfPwBwPc3Nn8pC1b9eE6xL3q3vA8WzJLd0F
OwIDAQAB
-----END PUBLIC KEY-----
`)
data := []byte("hello world")
encrypted, err := RSAEncrypt(data, publicKey)
if err != nil {
fmt.Println(err)
return
}
fmt.Println("encrypted:", encrypted)
}
- RSA解密
RSA解密需要指定私钥和密文,将密文转换为字节数组,再使用RSA私钥解密算法对字节数组进行解密,最后得到明文。
示例代码:
package main
import (
"crypto/rand"
"crypto/rsa"
"crypto/x509"
"encoding/base64"
"encoding/pem"
"fmt"
)
func RSADecrypt(encrypted string, privateKey []byte) ([]byte, error) {
// 解析私钥
block, _ := pem.Decode(privateKey)
if block == nil {
return nil, fmt.Errorf("failed to decode private key")
}
priv, err := x509.ParsePKCS1PrivateKey(block.Bytes)
if err != nil {
return nil, err
}
// 解密base64字符串
encryptedData, err := base64.StdEncoding.DecodeString(encrypted)
if err != nil {
return nil, err
}
// 解密
decrypted, err := rsa.DecryptPKCS1v15(rand.Reader, priv, encryptedData)
if err != nil {
return nil, err
}
return decrypted, nil
}
func main() {
privateKey := []byte(`
-----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEA1xOZlQJ6NnUg+RYd6JHgwq3Pq+g8/9F1M9Z6Ezr1rTm7YyBb
+eJwVvB+gJk7VX9Q2ZBhVvSf0Yt8zIc2Qw0f4LHz4JW8M+9XZKxJkq3zBpW8YjKz
J5+eDvQJQgW8F5GKj5I5EeSv+8bYt2BmGw1S4m4n8eJWgZL9dZKp3PvqzY5W5J76
dNwJf2QvM8is5W5j5LZP5/6KvJ6RlU6JcUwOyJL3q8HkWb1X9+VHxT1rAP7hTtT+
uJ0VzJ0sZs7VJfQs+9JI1ZM1hLrYzYj+TzwEwJGn6mJj7oDQ2sX1Zn0z6Uv1Rn/0
dUfPwBwPc3Nn8pC1b9eE6xL3q3vA8WzJLd0FOwIDAQABAoIBAQCFjvL5GZd5aX9H
iQ8v5RjyOQw0DbL+L8j8i5hOx4I7Xc0e4j4F4v4iFJLw63p/6rTf1eTjzHxN7sF9
WfV7Nv+Pb+GwLHjJHM2z6fRc6xhZ1mXZB3q3Bv3JnOyjKd+UdYzD0hTJvV7sQsZ9
VlJgC6fEtVwU+OgEo2QWYcRvHd6x0f6gj3h3qJ0p3FwLzgJf5Y8q3n5pBd5lZP5o
Q2Wm1Hn5eDyJiMzEjIySfLzvPdZ4N4pX4F4j4N4vQlJtllzgJP8LIkrW5zvKACJ4
0Zc9L4f4v+I4y1/kfJz5EzY3W0Gv3Zd5g5eXJ8H5W5RvRwVfU6jNz2QUDU6lJU6d
ZL9X9H3BAoGBAPvGwPzj+KdWHJYzrTjTJ7sZb6sXe7VzJ6PvA4JlGwVQ2oHvK8S5
pZn9oZa4Kc4L4eMO4y+5Ee0wBbwCv+qN3W5C5X5M5t5/1R8LQW6+Oy6VfA6lRz6J
QO9+9Dd1Z6p3Gq3JqjJd0wVz+TgTJrYzr6LX9CQZQJcZs7Vz0Bp0dVBAoGBAPfJh
nY1sZ9uV7sQhJlP8mWn+6LcVwUjz6Uv1Rn/0dUfPwBwPc3Nn8pC1b9eE6xL3q3vA8
WzJLd0FOwIDAQAB
-----END RSA PRIVATE KEY-----
`)
encrypted := "Q2fLzvS8WY9p0Xx7xOc4t4uz4hu4Ez+L1yFw3vLgWkq8P5H5G5hr5gRi5W2Q8t1n0y2IwKjFkzGmS9XpXbI4E4v4m1Es4FyxLJjOwVwJvYzrT+7jJ9ZsQs7sPcJW0V7OcZ6KjGwFbB6UQz6i9OHHxGjKv0OX6Oq3qzP6GjNwVb+6N2f6Q9/6B1kKd3N+LqM3qyNjJyPwVzJlYr1rYJ9XkZs7VJfQs+9JI1ZM1hLrYzYj+TzwEwJGn6mJj7oDQ2sX1Zn0z6Uv1Rn/0dUfPwBwPc3Nn8pC1b9eE6xL3q3vA8WzJLd0FOw=="
decrypted, err := RSADecrypt(encrypted, privateKey)
if err != nil {
fmt.Println(err)
return
}
fmt.Println("decrypted:", string(decrypted))
}