RSA加密失败因明文超长:1024位密钥限117字节,2048位限245字节;私钥解析失败多因PKCS#1与PKCS#8格式混淆;解密乱码源于byte转string的UTF-8强制编码;签名验签需确保哈希算法、密钥、数据完全一致。

公钥加密失败:panic: crypto/rsa: message too long 是什么鬼?
这是最常卡住新手的错误——rsa.EncryptPKCS1v15 直接 panic,不是代码写错,而是明文超长了。RSA 本身不能直接加密长数据,1024 位密钥最多只能加密 117 字节(128 − 11 padding),2048 位是 245 字节。超过就炸。
实操建议:
- 永远别对原始字符串直接调用
rsa.EncryptPKCS1v15,除非你确认长度 ≤pubKey.Size() - 11 - 分段加密必须手动切片,标准库不帮你做;推荐封装成
RsaPubEncrypt函数,每次取pubKey.Size() - 11字节加密,再拼接 - 如果要和 Java/PHP 互通,务必统一 padding 方式:Go 默认用
PKCS1v15,Java 侧得配"RSA/ECB/PKCS1Padding",别用 OAEP(默认参数不一致易出错)
私钥文件读不出来:failed to parse private key 怎么排?
这个错误表面是解析失败,根源八成是密钥格式不匹配。x509.ParsePKCS8PrivateKey 只认 PKCS#8 格式私钥,但 rsa.GenerateKey 默认生成的是 PKCS#1(RSA PRIVATE KEY PEM type),直接传进去就报错。
实操建议:
- 生成密钥时,私钥存为 PKCS#8:用
x509.MarshalPKCS8PrivateKey序列化,PEM blockType设为"PRIVATE KEY" - 读私钥时,先
pem.Decode,再根据 PEM header 判断类型:"RSA PRIVATE KEY"→ 用x509.ParsePKCS1PrivateKey;"PRIVATE KEY"→ 用x509.ParsePKCS8PrivateKey - 别手动生成或复制粘贴密钥内容——换行、空格、多余回车都会让
pem.Decode返回nilblock
加密后解密乱码:为什么 string(res) 不是原字符串?
这不是编码问题,是 Go 的 []byte 和字符串转换隐含陷阱。RSA 解密返回的是原始字节流,如果原数据含非 UTF-8 字符(比如二进制 payload、带 BOM 的文本、加密后的随机字节),string(res) 会强制转成 UTF-8,显示为 或乱码,但字节本身没错。
实操建议:
- 验证是否真解密失败:用
bytes.Equal(src, res)比字节,别依赖fmt.Println(string(res)) - 若原始数据是字符串,加密前确保它是合法 UTF-8(可用
utf8.Valid检查);若是任意二进制数据,加密/解密全程用[]byte,base64 编码后再打印或传输 - 别在加密流程里混用
string和[]byte转换,尤其涉及中文、emoji、加密中间结果时
签名验签失败:RSAVerify 返回 false 却没报错?
openssl.RSAVerify 或标准库 rsa.VerifyPKCS1v15 返回 false 不抛 error,容易误判为“逻辑通过”。实际可能是哈希算法不一致、公钥不匹配、甚至签名被截断(比如 base64 解码失败只取了前半段)。
实操建议:
- 签名和验签必须用同一哈希算法:比如都用
crypto.SHA256,且传给rsa.SignPKCS1v15和rsa.VerifyPKCS1v15的hash.Hash实例要一致(别一个用sha256.New(),另一个用sha512.New()) - 验签前检查签名长度:RSA-2048 签名长度固定为
256字节,如果 base64 解码后不是这个长度,直接 return false,不用进验签函数 - 私钥签名时,原文 hash 值必须和验签时完全一致——注意换行符、空格、BOM、JSON marshal 是否加了
SortKeys,这些细微差异会导致哈希不同
真正麻烦的从来不是“怎么调函数”,而是密钥格式、padding 规则、字节边界、哈希一致性这些看不见的链路。漏掉其中一环,表现就是“明明代码跑通了,结果不对”。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!











