rsa.encryptpkcs1v15 报 “message too long” 是因明文长度超过 rsa 密钥限制;2048 位密钥最多加密 245 字节(256−11);应采用 rsa+aes 混合加密,而非直接加密长数据。

rsa.EncryptPKCS1v15 为什么总 panic: crypto/rsa: message too long?
根本原因是明文长度超过 RSA 密钥允许的最大字节数。比如用 2048 位密钥时,rsa.EncryptPKCS1v15 最多只能加密 256 - 11 = 245 字节的原始数据(11 是 PKCS#1 v1.5 填充固定开销)。
- 别直接拿大 JSON 或长字符串喂给
rsa.EncryptPKCS1v15,它不是为大数据设计的 - 真实场景中,应该用 RSA 加密一个随机生成的 AES 密钥,再用这个 AES 密钥加密实际数据(混合加密)
- 如果硬要测小文本,确保
len(plaintext) ,可用 <code>rsa.Size()查密钥字节数 - 错误信息
crypto/rsa: message too long就是这个检查失败时 panic 的原样输出
如何正确加载 PEM 格式的私钥和公钥?
Go 的 crypto/rsa 不直接读 PEM 文件,得先用 crypto/x509 解码,再用 x509.ParsePKCS1PrivateKey 或 x509.ParsePKIXPublicKey 转成 *rsa.PrivateKey / *rsa.PublicKey。
- 私钥如果是 PKCS#8 格式(开头
-----BEGIN PRIVATE KEY-----),要用x509.ParsePKCS8PrivateKey,不是ParsePKCS1PrivateKey - 公钥常见两种:PKIX(
-----BEGIN PUBLIC KEY-----)用ParsePKIXPublicKey;PKCS#1(-----BEGIN RSA PUBLIC KEY-----)才用ParsePKCS1PublicKey - 记得检查解码后类型断言,比如
pubKey, ok := parsedKey.(*rsa.PublicKey),否则运行时 panic - PEM block type 写错(如把
PRIVATE KEY写成RSA PRIVATE KEY)会导致nil返回,不报错但后续调用Encrypt会 panic
rsa.DecryptPKCS1v15 解密失败返回 “crypto/rsa: decryption error” 怎么排查?
这个错误泛用性极强,不代表算法错了,大概率是输入不匹配——密文不是用对应私钥加密的,或填充方式不一致。
- 确认加密时用的是
rsa.EncryptPKCS1v15,解密必须配对用rsa.DecryptPKCS1v15;如果加密用了 OAEP,解密就得换rsa.DecryptOAEP - 密文必须是完整、未被截断的
[]byte,Base64 解码后长度应等于rsa.Size(privKey)(例如 2048 位密钥 → 256 字节) - 别在加密/解密前后对字节做额外编码(如 UTF-8 字符串强制转
[]byte再解码),原始字节流必须端到端一致 - 如果密文来自其他语言(如 Python 的
cryptography库),确认双方都用 PKCS#1 v1.5,且没有额外 base64 或 hex 编码混淆
要不要用 rsa.EncryptOAEP 替代 PKCS1v15?
该用。PKCS#1 v1.5 在理论上存在选择密文攻击风险(虽然实践中极难利用),而 rsa.EncryptOAEP 是更现代、带哈希绑定的安全方案,标准库也推荐它。
立即学习“go语言免费学习笔记(深入)”;
- OAEP 必须指定哈希函数(如
crypto.SHA256)和可选标签(label),加解密两端 label 必须完全一致 - OAEP 允许的明文上限比 PKCS#1 v1.5 更小:对 2048 位密钥,最多约
256 - 2*32 - 2 = 190字节(SHA256 输出 32 字节) - 加密时传
nil作为 label 是合法的,但解密时也得传nil,不能一个nil一个空字符串 - 如果你控制不了对方系统(比如对接老 Java 系统),那只能咬牙用 PKCS#1 v1.5;否则默认选 OAEP
加密本身不难,难的是密钥生命周期管理、填充一致性、字节流完整性这些细节。一个 rsa.Size() 没校验,或一行 PEM 类型写错,后面全是 panic。










