第4章:使用OpenSSL进行签名验签操作

4.1 OpenSSL基础与密码算法选择

OpenSSL,说白了就是一把瑞士军刀。做安全的人基本人手一份。我个人习惯把它当作HSM的"前置练习器"——在接入硬件设备之前,先用OpenSSL把流程跑通。

你可能会问:为什么不用更高级的工具?嗯,因为OpenSSL是底层工具,它能让你看清楚每一步到底在干什么。

4.2 支持的签名算法对比

先看一张表。这里是我这些年常用的签名算法对比。你想想看,选错了算法,后面全白干。

算法 密钥长度 签名长度 性能 适用场景
RSA 2048/4096 256/512字节 较慢 兼容性要求高
ECDSA 256/384 64/96字节 快 移动端/IoT
EdDSA 256 64字节 极快 高性能场景
SM2 256 64字节 较快 国密合规

我在项目中遇到过最头疼的事,就是客户拿着RSA-512的旧证书要求继续用。大哥,512位的RSA已经被破解了,你不换算法我就不接单。

4.3 数字签名核心流程

签名验签,说白了就是两件事:你用私钥签,别人用公钥验。下面这张图是我给团队培训时画的,后来成了我们的标准流程图。

数字签名与验签完整流程图 甲方:签名方 原始消息 (Message) 私钥签名 生成数字签名 传输原始消息 + 签名 乙方:验证方 原始消息 收到的签名 公钥验签 验证通过/失败 关键说明 • 私钥签名:使用摘要算法生成消息哈希,再使用私钥加密哈希值 • 公钥验签:消息重新计算哈希,用公钥解密签名并比对哈希值 • 签名本身不加密消息,它只保证身份和完整性

4.4 实操:生成密钥对

第一步,先生成私钥。我习惯用以下命令:

# 生成RSA私钥
openssl genrsa -out private_key.pem 2048

# 或者生成ECDSA私钥
openssl ecparam -genkey -name prime256v1 -out ec_private_key.pem

# 提取公钥
openssl rsa -in private_key.pem -pubout -out public_key.pem

私钥文件的权限必须设为600。我曾经看到新同事把私钥设成644,吓得我赶紧叫他改回来。你想想看,私钥泄露等于你家大门钥匙被别人配了一把。

4.5 实操:签名

有了密钥对,签名就简单了。完整的签名命令是这样:

# 对消息文件进行签名
openssl dgst -sha256 -sign private_key.pem -out signature.bin message.txt

# 查看签名的十六进制内容
xxd signature.bin | head -10

这里要注意:dgst命令会自动对消息做一次SHA-256哈希,然后才用私钥加密。你不用手动算哈希。为什么?因为OpenSSL替你做了,省得你犯错。

签名不要用PKCS#1 v1.5填充模式直接加密哈希。这不是标准签名流程,很多验证工具不认。我一直用dgst命令,省事又标准。

4.6 实操:验签

验签,说白了就是验证签名是否匹配。命令如下:

# 验签
openssl dgst -sha256 -verify public_key.pem \
    -signature signature.bin message.txt

# 输出示例
# Verified OK

# 如果消息被篡改
# Verification Failure

只有两种结果:"Verified OK"或"Verification Failure"。没有中间状态。

4.7 常见陷阱

我这些年踩过的坑,挑几个说说:

  • 文件编码问题:Windows和Linux的换行符不同。你在Windows上签名,在Linux上验签,结果可能不匹配。我建议始终统一使用二进制模式读写文件。
  • 摘要算法不匹配:签名用了SHA-256,验签却用了SHA-1。OpenSSL不会告诉你这个,只会给你一个"Verification Failure",你查半天都查不出来。
  • 密钥格式:PEM和DER格式互不兼容。我见过有人把PEM格式的私钥丢给要求DER格式的程序,然后说"OpenSSL有问题"。

记住一个原则:签名方和验签方必须使用完全相同的算法参数。密钥算法、曲线名称、摘要算法、编码格式,一个都不能错。

4.8 性能优化

如果你要批量签名,比如每秒几千次,裸用OpenSSL命令肯定不行。我建议:

  1. 使用OpenSSL的引擎接口,能加快RSA运算
  2. 考虑用ECDSA代替RSA,性能能提升3-5倍
  3. 如果追求极致性能,用EdDSA,实测比ECDSA还快一倍

我曾经为一个支付系统做优化,把签名时间从15ms降到了2ms。怎么做到的?就是把RSA-4096换成了ECDSA P-384,同时用OpenSSL引擎调用了硬件加速模块。说白了,算法和硬件都得选对。

嗯,OpenSSL这部分就先到这儿。用到的时候打开这个笔记,照着命令敲就行了。核心就三个动作:生成密钥对、签名、验签。记住算法要匹配,格式要一致,私钥要看死。