在Node.js中,一些加密方法(如crypto.createCipher
和crypto.createDecipher
)已经被废弃,推荐使用更安全的替代方法(如crypto.createCipheriv
和crypto.createDecipheriv
)。如果你需要将这些废弃的加密方法用Golang重构,以下是详细的步骤和代码示例。
假设你在Node.js中使用的是crypto.createCipher
和crypto.createDecipher
,这些方法使用的是AES加密算法,并且默认使用ECB模式(不推荐)或CBC模式。
例如,以下是一个使用crypto.createCipher
的Node.js代码示例:
const crypto = require('crypto');
function encrypt(text, key) {
const cipher = crypto.createCipher('aes-256-cbc', key);
let encrypted = cipher.update(text, 'utf8', 'hex');
encrypted += cipher.final('hex');
return encrypted;
}
function decrypt(encrypted, key) {
const decipher = crypto.createDecipher('aes-256-cbc', key);
let decrypted = decipher.update(encrypted, 'hex', 'utf8');
decrypted += decipher.final('utf8');
return decrypted;
}
const key = 'my-secret-key';
const text = 'Hello, World!';
const encrypted = encrypt(text, key);
console.log('Encrypted:', encrypted);
const decrypted = decrypt(encrypted, key);
console.log('Decrypted:', decrypted);
在Golang中,你可以使用crypto/aes
和crypto/cipher
包来实现相同的加密和解密功能。需要注意的是,Golang中的AES加密需要明确的IV(初始化向量),并且通常使用CBC模式。
以下是一个使用Golang实现相同功能的示例:
package main
import (
"crypto/aes"
"crypto/cipher"
"crypto/md5"
"crypto/rand"
"encoding/hex"
"errors"
"fmt"
"io"
)
// 生成密钥的MD5哈希
func createHash(key string) string {
hasher := md5.New()
hasher.Write([]byte(key))
return hex.EncodeToString(hasher.Sum(nil))
}
// 加密函数
func encrypt(data []byte, passphrase string) ([]byte, error) {
block, err := aes.NewCipher([]byte(createHash(passphrase)))
if err != nil {
return nil, err
}
// 生成随机的IV
iv := make([]byte, aes.BlockSize)
if _, err := io.ReadFull(rand.Reader, iv); err != nil {
return nil, err
}
// 使用CBC模式加密
stream := cipher.NewCBCEncrypter(block, iv)
paddedData := pkcs7Pad(data, aes.BlockSize)
encrypted := make([]byte, len(paddedData))
stream.CryptBlocks(encrypted, paddedData)
// 将IV和加密数据合并
return append(iv, encrypted...), nil
}
// 解密函数
func decrypt(data []byte, passphrase string) ([]byte, error) {
block, err := aes.NewCipher([]byte(createHash(passphrase)))
if err != nil {
return nil, err
}
if len(data) < aes.BlockSize {
return nil, errors.New("ciphertext too short")
}
// 提取IV
iv := data[:aes.BlockSize]
data = data[aes.BlockSize:]
// 使用CBC模式解密
stream := cipher.NewCBCDecrypter(block, iv)
decrypted := make([]byte, len(data))
stream.CryptBlocks(decrypted, data)
// 去除填充
return pkcs7Unpad(decrypted, aes.BlockSize)
}
// PKCS7填充
func pkcs7Pad(data []byte, blockSize int) []byte {
padding := blockSize - len(data)%blockSize
padtext := bytes.Repeat([]byte{byte(padding)}, padding)
return append(data, padtext...)
}
// PKCS7去填充
func pkcs7Unpad(data []byte, blockSize int) ([]byte, error) {
length := len(data)
if length == 0 {
return nil, errors.New("invalid padding")
}
padding := int(data[length-1])
if padding > blockSize || padding == 0 {
return nil, errors.New("invalid padding")
}
for i := length - padding; i < length; i++ {
if int(data[i]) != padding {
return nil, errors.New("invalid padding")
}
}
return data[:length-padding], nil
}
func main() {
key := "my-secret-key"
text := "Hello, World!"
encrypted, err := encrypt([]byte(text), key)
if err != nil {
fmt.Println("Encryption error:", err)
return
}
fmt.Println("Encrypted:", hex.EncodeToString(encrypted))
decrypted, err := decrypt(encrypted, key)
if err != nil {
fmt.Println("Decryption error:", err)
return
}
fmt.Println("Decrypted:", string(decrypted))
}
crypto.createCipher
会自动处理密钥的哈希。在Golang中,我们使用MD5哈希来生成一个32字节的密钥。crypto.createCipher
的默认模式。通过以上步骤,你可以将Node.js中废弃的加密方法安全地重构为Golang实现。