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 签名验签的标准流程

搞清了算法,流程本身其实不复杂。我拆成两步说。

签名生成(私钥干活):

  1. 客户端拿到原文 M
  2. 对 M 做摘要,得到 h(M)
  3. 把 h(M) 送去HSM
  4. HSM用私钥对 h(M) 签名,输出签名值 Sig
  5. 返回 (M, Sig) 给下游

验签过程(公钥干活):

  1. 接收方拿到 (M, Sig)
  2. 对 M 做同样的摘要,得到 h(M)'
  3. 把 h(M)' 和 Sig 发给HSM(或自己用公钥算)
  4. HSM验签,返回成功或失败
核心要点: 压测的时候,大多数人只压签名,觉得验签不重要。但我告诉你,验签的吞吐量往往更重要。因为一次签名可能只服务一个客户端,但验签可能被成百上千的对端同时调用。我在做金融支付网关压测时,签名请求每秒几百,验签请求每秒几万。那才是真正的瓶颈。

SVG流程图会把这个过程可视化出来,方便你对照理解。

签名验签核心流程 签名与验签核心流程 签名阶段(私钥执行) 验签阶段(公钥执行) 原始消息 M 摘要 h(M) → SHA256/SM3 HSM 私钥签名 输出 (M, Sig) 收到 (M, Sig) 重新摘要 h(M)' HSM 公钥验签 成功/失败 关键区别: 摘要算法必须在HSM外提前算好?不一定。部分HSM支持内部摘要, 但压测时通常选择外部算摘要,减少HSM的CPU占用,提升tps。 单次签名 = 1次摘要 + 1次私钥操作 单次验签 = 1次摘要 + 1次公钥操作 压测关注点:签名TPS vs 验签TPS

从图里可以清楚看到,签名和验签的前置步骤基本一致,区别只在最后一步用的是私钥还是公钥。这个模型对你设计压测脚本很关键——很多新手把签名和验签当成两个独立的黑盒,忽略了它们共享摘要计算的事实。

最后补一句。很多人问我:“为什么验签比签名快?” 拿RSA举例,签名时需要用到私钥的模幂运算,计算量大;而验签用的是公钥里的小指数(通常是65537),算得快。ECDSA和SM2也类似。所以当你做压测时,验签的tps通常是签名tps的3到10倍。这个比例心里要有数。

实践建议: 我个人习惯,在同一个测试场景里,先压签名,再压验签。两者数据对比着看。如果验签慢于签名,那要么是HSM配置有问题,要么是你摘要算法选错了。别问我怎么知道的——我曾经花了三天才找到原因,结果是HSM的密钥被设置了“仅限签名”策略。