2. 签名验签基础:非对称加密与摘要算法
做压测之前,咱们得先把签名验签这件事儿掰扯清楚。
说白了,签名验签就干两件事:证明“你是谁”,以及证明“东西没被改过”。你想想看,在HSM里,私钥是永远不出来的。签名是私钥干的活,验签是公钥干的活。这个模型如果不理解,后面压测的指标全都是瞎的。
2.1 摘要算法:签名的第一道工序
签名不能直接签整份原始数据。为啥?太慢了。一个文件几GB,非对称加密算起来能把你急死。
所以实际做法是:先对原文做摘要(Hash),得到固定长度的摘要值。然后再对这个摘要值签名。
常见的摘要算法就这么几个:
| 算法 | 输出长度(bit) | 安全级别 | 我个人的看法 |
|---|---|---|---|
| SHA256 | 256 | 高(当前标准) | 最稳妥,通用性最好。我在项目中基本上90%的场景都用它。 |
| SHA384 | 384 | 更高 | 国密SM2强制配套使用,不支持也得支持。 |
| SHA512 | 512 | 极高 | 有点重了,压测时tps会掉得比较明显。 |
| SM3 | 256 | 国密标准 | 国密体系必选。嗯,要注意它和SHA256不是等价的,速度也有差异。 |
一点经验: 我自己算过SHA256的碰撞概率,那数字比宇宙里的原子加起来还大。所以别担心“万一撞了怎么办”,那是物理上几乎不可能的事。真正该担心的是算法实现的正确性,比如在HSM里摘要字节序对不对,这个坑我踩过。
2.2 非对称加密算法:RSA、ECDSA、SM2
非对称加密,就是加密和解密用不同的钥匙。一把公开叫公钥,一把私藏叫私钥。签名时,私钥签名,公钥验签。
这三种算法是目前的主流。差距在哪?我直接给结论:
- RSA: 老大哥。支持加密和签名,密钥可以到4096位。但慢,真的很慢。RSA 4096签名,在普通软件里每秒可能就几百次。在HSM里,如果不开硬件加速,也快不到哪去。
- ECDSA: 椭圆曲线版。密钥短(256位就很安全了),速度快。我习惯在性能优先的场景优先考虑它。但要注意曲线选择。P256是最常见的。
- SM2: 国标。本质上也是一种椭圆曲线算法。密钥长度256位。性能跟ECDSA P256差不多,但国内合规必选。我在金融项目里被要求必须用SM2,那时候才算真的摸透了它。
具体差异可以看这张表:
| 特性 | RSA-2048 | ECDSA P-256 | SM2 |
|---|---|---|---|
| 密钥生成 | 很慢(需要找大素数) | 快 | 快 |
| 签名性能 | 中等 | 高 | 高 |
| 验签性能 | 快(比签名快很多) | 快 | 快 |
| 签名长度 | 256字节 | 64~72字节 | 64字节 |
| 合规 | 全球通用 | 全球通用 | 国内必须 |
避坑: 我曾经见过有人直接用RAW RSA做签名,就是没有加PSS填充。这在很多老旧系统里是允许的,但在金融合规场景下会被打回。一定要用PKCS#1 v1.5或者PSS填充。PSS更安全,但也更耗性能。压测的时候要明确知道你用的是哪种。
2.3 签名验签的标准流程
搞清了算法,流程本身其实不复杂。我拆成两步说。
签名生成(私钥干活):
- 客户端拿到原文
M - 对
M做摘要,得到h(M) - 把
h(M)送去HSM - HSM用私钥对
h(M)签名,输出签名值Sig - 返回
(M, Sig)给下游
验签过程(公钥干活):
- 接收方拿到
(M, Sig) - 对
M做同样的摘要,得到h(M)' - 把
h(M)'和Sig发给HSM(或自己用公钥算) - HSM验签,返回成功或失败
核心要点: 压测的时候,大多数人只压签名,觉得验签不重要。但我告诉你,验签的吞吐量往往更重要。因为一次签名可能只服务一个客户端,但验签可能被成百上千的对端同时调用。我在做金融支付网关压测时,签名请求每秒几百,验签请求每秒几万。那才是真正的瓶颈。
SVG流程图会把这个过程可视化出来,方便你对照理解。
从图里可以清楚看到,签名和验签的前置步骤基本一致,区别只在最后一步用的是私钥还是公钥。这个模型对你设计压测脚本很关键——很多新手把签名和验签当成两个独立的黑盒,忽略了它们共享摘要计算的事实。
最后补一句。很多人问我:“为什么验签比签名快?” 拿RSA举例,签名时需要用到私钥的模幂运算,计算量大;而验签用的是公钥里的小指数(通常是65537),算得快。ECDSA和SM2也类似。所以当你做压测时,验签的tps通常是签名tps的3到10倍。这个比例心里要有数。
实践建议: 我个人习惯,在同一个测试场景里,先压签名,再压验签。两者数据对比着看。如果验签慢于签名,那要么是HSM配置有问题,要么是你摘要算法选错了。别问我怎么知道的——我曾经花了三天才找到原因,结果是HSM的密钥被设置了“仅限签名”策略。