优先选rsa.SignPSS:它带随机盐值、抗选择明文攻击,更安全;rsa.SignPKCS1v15仅用于兼容老系统。签名前必须手动哈希原文并传摘要字节,哈希算法须与验签端严格一致,签名结果需Base64 URL-safe编码传输。

签名时用 rsa.SignPKCS1v15 还是 rsa.SignPSS?
两者都可用,但推荐优先选 rsa.SignPSS:它带随机盐值、抗长度扩展攻击,是当前更安全的默认选择。而 rsa.SignPKCS1v15 虽兼容老系统(比如某些硬件签名模块),但已知存在理论上的填充预言攻击风险,除非明确对接遗留服务,否则别主动降级。
实际签名前必须哈希原始字符串——rsa.SignPSS 要求传入已哈希的 []byte 和对应哈希算法(如 crypto.SHA256),不能直接传原文;rsa.SignPKCS1v15 同理,需先调用 hash.Sum() 得到摘要。
- 别漏掉哈希步骤:直接对明文签名会 panic 或返回错误
- 哈希算法要和验签端严格一致,SHA256 就全程 SHA256,混用 SHA512 会导致验签失败
-
rsa.SignPSS的 salt 长度建议设为hash.Size()(即 32 字节 for SHA256),太短削弱安全性,太长可能被某些旧解析器拒绝
私钥签名后得到的 []byte 怎么安全传输?
签名结果是原始二进制字节,不能直接拼进 JSON 或 HTTP header;必须编码。最常用且无歧义的是 Base64 URL-safe 编码(base64.URLEncoding.EncodeToString),它不含 +、/ 和换行,适合 URL、JWT、HTTP 参数等场景。
别用标准 Base64(base64.StdEncoding),它的 + 和 / 在 URL 中需额外 percent-encode,徒增出错可能;也别手写 hex 编码——体积翻倍,传输效率低。
初始化并管理阿里云SDK Go 客户端,涵盖 sync.Once 单例、goroutine 安全、endpoint 与 region 配置、VPC 端点及调试。
立即学习“go语言免费学习笔记(深入)”;
- 验签端必须用同一套编码解码:
base64.URLEncoding.DecodeString - 如果签名嵌入 JSON,确保字段类型为 string,而非 base64 后误当 byte slice 处理
- 传输层(如 HTTPS)不改变签名字节内容,但别在中间件里做 trim、lowercase 等隐式转换
公钥验签失败常见原因有哪些?
90% 的验签失败不是算法问题,而是数据不一致。典型现象:x509: certificate signed by unknown authority(这是证书链错误,和纯 RSA 验签无关)、crypto/rsa: verification error(真验签失败)、或 panic 报 “hash mismatch”。
- 原文被意外修改:空格、换行、BOM、JSON 序列化顺序差异(如 map key 排序)都会导致哈希值不同
- 公钥格式不对:PEM 块必须是
-----BEGIN PUBLIC KEY-----,不是-----BEGIN RSA PUBLIC KEY-----(后者是 PKCS#1 格式,需用x509.ParsePKIXPublicKey解析前者,x509.ParsePKCS1PublicKey解析后者) - 签名时用了 PSS 但验签用 PKCS1v15(或反之),算法必须完全匹配
- 验签用的哈希对象没重置:重复使用同一个
hash.Hash实例未调Reset(),导致哈希值累积
如何从 PEM 文件加载私钥和公钥?
Go 的 crypto/x509 包不直接读文件,需手动读取 PEM 块再解析。私钥通常有密码保护,但生产环境建议密钥已由外部 KMS 管理,本地只存无密钥 PEM;若真要解密,用 x509.DecryptPEMBlock,但注意 Go 1.22+ 已弃用该函数,应改用 pkcs8 解析。
关键点:私钥 PEM 块 type 是 "RSA PRIVATE KEY"(PKCS#1)或 "PRIVATE KEY"(PKCS#8);公钥对应是 "RSA PUBLIC KEY" 或 "PUBLIC KEY"。混用会解析失败。
- 用
pem.Decode提取 block 后,检查block.Type再决定调哪个解析函数 - PKCS#8 私钥(
"PRIVATE KEY")必须用x509.ParsePKCS8PrivateKey,不能用ParsePKCS1PrivateKey - 公钥推荐统一用
x509.ParsePKIXPublicKey,它能处理"PUBLIC KEY"(PKIX)和"RSA PUBLIC KEY"(PKCS#1)两种格式

















