在Node.js中,一些加密方法(如createCipher
和createDecipher
)已经被废弃,推荐使用更安全的替代方法(如createCipheriv
和createDecipheriv
)。如果你需要将这些加密逻辑迁移到Golang中,可以使用Golang的crypto
包来实现相同的功能。
createCipheriv
)假设你在Node.js中使用createCipheriv
进行AES-256-CBC加密:
const crypto = require('crypto');
const algorithm = 'aes-256-cbc';
const key = crypto.randomBytes(32); // 256-bit key
const iv = crypto.randomBytes(16); // 128-bit IV
function encrypt(text) {
let cipher = crypto.createCipheriv(algorithm, key, iv);
let encrypted = cipher.update(text, 'utf8', 'hex');
encrypted += cipher.final('hex');
return encrypted;
}
function decrypt(encrypted) {
let decipher = crypto.createDecipheriv(algorithm, key, iv);
let decrypted = decipher.update(encrypted, 'hex', 'utf8');
decrypted += decipher.final('utf8');
return decrypted;
}
const text = 'Hello, World!';
const encrypted = encrypt(text);
console.log('Encrypted:', encrypted);
const decrypted = decrypt(encrypted);
console.log('Decrypted:', decrypted);
在Golang中,你可以使用crypto/aes
和crypto/cipher
包来实现相同的AES-256-CBC加密和解密。
package main
import (
"crypto/aes"
"crypto/cipher"
"crypto/rand"
"encoding/hex"
"fmt"
"io"
)
func encrypt(text string, key []byte, iv []byte) (string, error) {
block, err := aes.NewCipher(key)
if err != nil {
return "", err
}
plaintext := []byte(text)
ciphertext := make([]byte, len(plaintext))
mode := cipher.NewCBCEncrypter(block, iv)
mode.CryptBlocks(ciphertext, plaintext)
return hex.EncodeToString(ciphertext), nil
}
func decrypt(encrypted string, key []byte, iv []byte) (string, error) {
block, err := aes.NewCipher(key)
if err != nil {
return "", err
}
ciphertext, err := hex.DecodeString(encrypted)
if err != nil {
return "", err
}
plaintext := make([]byte, len(ciphertext))
mode := cipher.NewCBCDecrypter(block, iv)
mode.CryptBlocks(plaintext, ciphertext)
return string(plaintext), nil
}
func main() {
key := make([]byte, 32) // 256-bit key
if _, err := io.ReadFull(rand.Reader, key); err != nil {
panic(err)
}
iv := make([]byte, aes.BlockSize) // 128-bit IV
if _, err := io.ReadFull(rand.Reader, iv); err != nil {
panic(err)
}
text := "Hello, World!"
encrypted, err := encrypt(text, key, iv)
if err != nil {
panic(err)
}
fmt.Println("Encrypted:", encrypted)
decrypted, err := decrypt(encrypted, key, iv)
if err != nil {
panic(err)
}
fmt.Println("Decrypted:", decrypted)
}
crypto/rand
包生成随机的密钥和IV,确保安全性。crypto/aes
和crypto/cipher
包来实现AES-256-CBC加密和解密。hex.EncodeToString
和hex.DecodeString
来进行编码和解码。如果你需要处理填充,可以使用以下代码:
func pkcs7Pad(data []byte, blockSize int) []byte {
padding := blockSize - len(data)%blockSize
padtext := bytes.Repeat([]byte{byte(padding)}, padding)
return append(data, padtext...)
}
func pkcs7Unpad(data []byte) ([]byte, error) {
length := len(data)
if length == 0 {
return nil, fmt.Errorf("invalid padding")
}
padding := int(data[length-1])
if padding > length {
return nil, fmt.Errorf("invalid padding")
}
return data[:length-padding], nil
}
在加密和解密时使用这些函数来处理填充。
package main
import (
"bytes"
"crypto/aes"
"crypto/cipher"
"crypto/rand"
"encoding/hex"
"fmt"
"io"
)
func pkcs7Pad(data []byte, blockSize int) []byte {
padding := blockSize - len(data)%blockSize
padtext := bytes.Repeat([]byte{byte(padding)}, padding)
return append(data, padtext...)
}
func pkcs7Unpad(data []byte) ([]byte, error) {
length := len(data)
if length == 0 {
return nil, fmt.Errorf("invalid padding")
}
padding := int(data[length-1])
if padding > length {
return nil, fmt.Errorf("invalid padding")
}
return data[:length-padding], nil
}
func encrypt(text string, key []byte, iv []byte) (string, error) {
block, err := aes.NewCipher(key)
if err != nil {
return "", err
}
plaintext := pkcs7Pad([]byte(text), aes.BlockSize)
ciphertext := make([]byte, len(plaintext))
mode := cipher.NewCBCEncrypter(block, iv)
mode.CryptBlocks(ciphertext, plaintext)
return hex.EncodeToString(ciphertext), nil
}
func decrypt(encrypted string, key []byte, iv []byte) (string, error) {
block, err := aes.NewCipher(key)
if err != nil {
return "", err
}
ciphertext, err := hex.DecodeString(encrypted)
if err != nil {
return "", err
}
plaintext := make([]byte, len(ciphertext))
mode := cipher.NewCBCDecrypter(block, iv)
mode.CryptBlocks(plaintext, ciphertext)
plaintext, err = pkcs7Unpad(plaintext)
if err != nil {
return "", err
}
return string(plaintext), nil
}
func main() {
key := make([]byte, 32) // 256-bit key
if _, err := io.ReadFull(rand.Reader, key); err != nil {
panic(err)
}
iv := make([]byte, aes.BlockSize) // 128-bit IV
if _, err := io.ReadFull(rand.Reader, iv); err != nil {
panic(err)
}
text := "Hello, World!"
encrypted, err := encrypt(text, key, iv)
if err != nil {
panic(err)
}
fmt.Println("Encrypted:", encrypted)
decrypted, err := decrypt(encrypted, key, iv)
if err != nil {
panic(err)
}
fmt.Println("Decrypted:", decrypted)
}
通过这种方式,你可以安全地将Node.js中的废弃加密方法迁移到Golang中,并确保加密过程的安全性。