天天看点

go语言实现数据加密和数据解密

作者:浪迹天涯的外乡人

Go语言中提供了多种加密、解密算法,本文介绍其中的两种:AES和RSA。

一、AES加密解密

AES是一种对称加密算法,即加密和解密使用同一把密钥。Go语言中提供了crypto/aes包来实现AES加密解密。

  1. 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)
}
           
  1. 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加密解密。

  1. 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)
}
           
  1. 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))
}
           

继续阅读