如何使用Golang crypto实现加密和解密_RSA和AES示例

Go中应使用RSA-OAEP加密小数据(如AES密钥),AES-GCM实现安全对称加密;需用crypto/rand生成随机数,避免重用nonce,严禁直接RSA加密长消息或使用不安全AES模式。

Go 标准库的 crypto 包提供了安全、高效的加密原语,RSA 和 AES 是最常用的非对称与对称加密算法。下面用简洁、可运行的示例说明如何在 Go 中正确实现 RSA 密钥生成、加密/解密,以及 AES-GCM(推荐)加解密,强调关键细节和常见陷阱。

生成并使用 RSA 密钥对(PKCS#1 v1.5 或 OAEP)

RSA 适合加密小数据(如 AES 密钥),不直接加密长消息。Go 推荐使用 OAEP(带随机盐,更安全),而非旧式 PKCS#1 v1.5。

  • 生成 2048 位私钥:priv, err := rsa.GenerateKey(rand.Reader, 2048)
  • 公钥加密(OAEP,使用 SHA256):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 加密与解密(推荐对称方案)

AES-GCM 提供加密+认证(AEAD),防篡改,无需手动管理 IV 和 MAC。密钥必须为 16(AES-128)、24(AES-192)或 32(AES-256)字节。

  • 生成随机 12 字节 nonce(GCM 要求):nonce := make([]byte, 12); rand.Read(nonce)
  • 创建 cipher: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 和完整密文)
  • 关键:nonce 绝对不可重用;建议将 nonce 存在密文前(如 append(nonce, ciphertext...)),解密时切分

组合使用 RSA + AES 实现混合加密

典型场景:用 RSA 加密一个随机 AES 密钥,再用该 AES 密钥加密大段数据。

  • 生成 32 字节 AES 密钥:aesKey := make([]byte, 32); rand.Read(aesKey)
  • 用 RSA 公钥加密 aesKey → 得到 encryptedAesKey
  • aesKey + GCM 加密原始数据 → 得到 aesCiphertext
  • 最终密文结构可为:len(encryptedAesKey) || encryptedAesKey || nonce || aesCiphertext
  • 解密时先用 RSA 私钥恢复 aesKey,再用它和 nonce 解密 AES 密文

注意事项与避坑提示

安全不是默认的,细节决定成败:

  • 永远使用 crypto/rand(非 math/rand)生成密钥、nonce、salt
  • RSA 不要用于直接加密用户输入;AES 模式只选 GCM 或 CCM,避免 ECB、CBC(需额外处理 padding 和 MAC)
  • 私钥务必保密,公钥可公开;保存私钥建议用 PEM 编码 + 密码保护(需额外集成 golang.org/x/crypto/pkcs12pkcs8
  • 所有错误都应检查,尤其 Open 失败意味着密文被篡改或密钥错误