go中rsa加密需严守三要素:密钥生成(用crypto/rand、长度2048+、指数为*big.int)、填充方式(pkcs1v15明文≤pub.size()-11字节或oaep配对使用)、pem解析(头尾匹配且必须类型断言)。

Go 里用 crypto/rsa 做非对称加密,不是“调个函数就完事”,而是密钥生成、填充方式、字节流处理三者必须严丝合缝;任一错位,crypto/rsa: message too long 或 crypto/rsa: decryption error 就立刻报给你看。
rsa.GenerateKey 必须用 crypto/rand.Reader,且长度只能是 2048/3072/4096
私钥安全性完全依赖随机源——用 math/rand(哪怕只是 rand.New(rand.NewSource(time.Now().UnixNano())))生成的密钥可预测,等于没加密。运行时可能 panic:crypto/rsa: invalid prime: not prime,也可能静默失败:加密后解不开。
-
rsa.GenerateKey(rand.Reader, 2048)合法;rsa.GenerateKey(rand.Reader, 2000)直接 panic - 1024 已被 TLS 弃用,生产环境别用;推荐起步就选
3072或4096 - 公钥指数必须是
*big.Int,写65537会 panic;正确写法:e := new(big.Int).SetInt64(65537)
EncryptPKCS1v15 明文长度不能超 publicKey.Size() − 11
这是硬性限制,不是配置问题。publicKey.Size() 返回的是密钥字节数(如 2048 位 → 256 字节),减去 PKCS#1 v1.5 固定填充 11 字节,就是最大明文字节数(256 − 11 = 245)。中文 UTF-8 编码下,一个汉字占 2~3 字节,245 字节 ≈ 80 多个汉字。
- 别用
len(plaintext)判断长度(那是 rune 数);必须用len([]byte(plaintext)) - 加密前务必校验:
if len(data) > pub.Size()-11 { panic("message too long") } - 真实业务中,绝不要直接加密 JSON、token 或文件;应走混合加密:用
crypto/aes加密原始数据,再用 RSA 加密那个随机 AES 密钥
PEM 解析必须匹配头尾类型,且要断言类型
私钥 PEM 块头决定了该用哪个解析函数,且返回值必须显式断言为 *rsa.PrivateKey,否则后续解密必 panic。
-
-----BEGIN RSA PRIVATE KEY-----→ 用x509.ParsePKCS1PrivateKey -
-----BEGIN PRIVATE KEY-----→ 用x509.ParsePKCS8PrivateKey(推荐,支持 3072+) - 两个函数解析失败都只返回
nil,不报错;必须检查:if privKey, ok := parsedKey.(*rsa.PrivateKey); !ok { panic("not a valid rsa private key") } - 公钥同理:
-----BEGIN RSA PUBLIC KEY-----→x509.ParsePKCS1PublicKey;-----BEGIN PUBLIC KEY-----→x509.ParsePKIXPublicKey
EncryptOAEP 和 EncryptPKCS1v15 绝对不能混用
加密和解密函数必须成对使用,参数也必须一致。混用不会提示具体原因,统一返回 crypto/rsa: decryption error,排查极难。
-
rsa.EncryptPKCS1v15↔rsa.DecryptPKCS1v15(第一个参数必须是*rsa.PrivateKey) -
rsa.EncryptOAEP↔rsa.DecryptOAEP(哈希函数如sha256.New()、label 如[]byte("auth")必须两端完全一致) - 密文传输前常做 base64 编码,但解密前必须用
base64.StdEncoding.DecodeString还原为原始[]byte;传 ASCII 字符串进去,必然失败
最容易被忽略的其实是密钥加载环节:PEM 解析不报错但返回 nil,类型断言跳过,私钥变量实际是 nil,直到调用 DecryptPKCS1v15 才 panic。这个空指针陷阱,在日志里看不出任何线索,只能靠提前断言兜底。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!











