Go中应使用RSA-OAEP加密小数据(如AES密钥),AES-GCM实现安全对称加密;需用crypto/rand生成随机数,避免重用nonce,严禁直接RSA加密长消息或使用不安全AES模式。
Go 标准库的 crypto 包提供了安全、高效的加密原语,RSA 和 AES 是最常用的非对称与对称加密算法。下面用简洁、可运行的示例说明如何在 Go 中正确实现 RSA 密钥生成、加密/解密,以及 AES-GCM(推荐)加解密,强调关键细节和常见陷阱。
RSA 适合加密小数据(如 AES 密钥),不直接加密长消息。Go 推荐使用 OAEP(带随机盐,更安全),而非旧式 PKCS#1 v1.5。
priv, err := rsa.GenerateKey(rand.Reader, 2048)
rsa.EncryptOAEP(sha256.New(), rand.Reader, &priv.PublicKey, plaintext, nil)
rsa.DecryptOAEP(sha256.New(), rand.Reader, priv, ciphertext, nil)
pub.Size() - 2*hash.Size() - 2(OAEP),例如 2048 位密钥约支持最多 190 字节
AES-GCM 提供加密+认证(AEAD),防篡改,无需手动管理 IV 和 MAC。密钥必须为 16(AES-128)、24(AES-192)或 32(AES-256)字节。
成随机 12 字节 nonce(GCM 要求):nonce := make([]byte, 12); rand.Read(nonce)
aesgcm, _ := cipher.NewGCM(block)(block 来自 aes.NewCipher(key))ciphertext := aesgcm.Seal(nil, nonce, plaintext, nil)(输出 = nonce + ciphertext)plaintext, err := aesgcm.Open(nil, nonce, ciphertext, nil)(需传入原始 nonce 和完整密文)append(nonce, ciphertext...)),解密时切分典型场景:用 RSA 加密一个随机 AES 密钥,再用该 AES 密钥加密大段数据。
aesKey := make([]byte, 32); rand.Read(aesKey)
aesKey → 得到 encryptedAesKey
aesKey + GCM 加密原始数据 → 得到 aesCiphertext
len(encryptedAesKey) || encryptedAesKey || nonce || aesCiphertext
aesKey,再用它和 nonce 解密 AES 密文安全不是默认的,细节决定成败:
crypto/rand(非 math/rand)生成密钥、nonce、saltgolang.org/x/crypto/pkcs12 或 pkcs8)Open 失败意味着密文被篡改或密钥错误