Go中RSA密钥生成需显式指定≥2048位(推荐3072),用crypto/rand.Reader;加密必须选PKCS#1v1.5或OAEP填充,解密失败多因密文长度错、填充不匹配或私钥格式误。

golang 中用 crypto/rsa 生成密钥对要指定私钥位数
Go 标准库不提供默认密钥长度,rsa.GenerateKey 必须显式传入 *rand.Reader 和位数(如 2048),少于 2048 位在现代场景中已不安全,OpenSSL 默认也已弃用 1024。
常见错误是传了 nil 的随机源或硬编码 1024——前者 panic,后者被拒签或报 x509: RSA key missing NULL parameters。
- 用
crypto/rand.Reader,别用math/rand - 生产环境至少用
2048,推荐3072 - 私钥导出必须用
PKCS#1(rsa.PrivateKey)或PKCS#8(pkcs8.MarshalPrivateKey),公钥固定为PKIX(ssh.MarshalPKIXPublicKey或x509.MarshalPKIXPublicKey)
加密时必须用 rsa.EncryptPKCS1v15 或 rsa.EncryptOAEP
Go 不允许直接对明文调用 rsa.Encrypt,必须选填充方案。PKCS#1 v1.5 兼容性好但有理论漏洞;OAEP 更安全但需指定哈希(如 sha256.New)和可选标签(label)。
典型错误:用 v1.5 加密超长数据(明文长度不能超过 keySizeInBytes - 11),或 OAEP 中哈希函数与解密端不一致导致 crypto/rsa: decryption error。
立即学习“go语言免费学习笔记(深入)”;
Go 配置库,使用 spf13/viper — 分层优先级(flag > env >file > KV > default),提供 BindPFlag/BindPFlags、SetEnvPrefix + SetEnvKeyReplace 等功能。
- v1.5 适合短 token、JWT header 等小数据,最大明文 =
(rsa.PublicKey.Size() - 11) - OAEP 推荐用于敏感字段,注意两端
hash和label必须完全一致 - 别把私钥当公钥传进
Encrypt*函数——会 panic:crypto/rsa: public key must be *rsa.PublicKey
解密失败大概率是密文被篡改或填充不匹配
rsa.DecryptPKCS1v15 和 rsa.DecryptOAEP 在输入非法时都返回通用错误 crypto/rsa: decryption error,不透露具体原因,这是故意设计的安全特性。但实际调试时,90% 是以下三种情况:
- 密文被 base64 解码后长度 ≠
rsa.PrivateKey.Size()(比如少了一位 padding 或换行符干扰) - 加密用 v1.5,解密用了 OAEP(或反过来)
- 私钥格式不对:从 PEM 读取时漏了
-----BEGIN RSA PRIVATE KEY-----头尾,或误用了 PKCS#8 私钥但没用pkcs8.ParsePrivateKey
建议加一层校验:len(ciphertext) == priv.Size(),再进解密;私钥加载后打印 priv.PublicKey.N.BitLen() 确认位数是否与加密端一致。
公钥加密 + 私钥解密只是基础,签名验签才是 RSA 主流用途
很多人用 RSA 做“加密通信”,但 Go 中更常见、更合理的模式是:用对方公钥加密对称密钥(如 AES key),再用该密钥加密正文(混合加密);或者直接用私钥签名、公钥验签(如 JWT、API 请求认证)。
签名函数是 rsa.SignPKCS1v15 / rsa.SignPSS,验签是 rsa.VerifyPKCS1v15 / rsa.VerifyPSS。注意:签名对象是摘要(sha256.Sum256(data).[:] ),不是原始数据;PSS 需额外传 crypto.Hash 和 *rsa.PSSOptions。
容易忽略的点:验签时若用 VerifyPKCS1v15 但签名是 PSS 生成的,错误仍是泛化的 crypto/rsa: verification error,无提示。

















