ECDSA(Elliptic Curve Digital Signature Algorithm)是基于椭圆曲线密码学的数字签名算法,广泛应用于比特币、区块链以及 TLS 证书中。本文介绍其原理及 OpenSSL 命令行操作。

什么是 ECDSA?

ECDSA 是 DSA(Digital Signature Algorithm)的椭圆曲线版本,利用椭圆曲线离散对数问题的计算难度来保证签名安全性。相比传统 RSA,ECDSA 在相同安全强度下密钥更短,运算更快。

常见曲线

曲线 位数 应用场景
prime256v1 (P-256) 256 位 主流 TLS 证书、Web 应用
secp384r1 (P-384) 384 位 高安全场景、政府、金融
secp521r1 (P-521) 521 位 极高安全需求

生成 ECDSA 密钥对

生成私钥

1
2
3
openssl genpkey -algorithm EC \
    -pkeyopt ec_paramgen_curve:prime256v1 \
    -out ecdsa_private.pem

导出公钥

1
openssl pkey -in ecdsa_private.pem -pubout -out ecdsa_public.pem

查看密钥详情

1
openssl pkey -in ecdsa_private.pem -text -noout

输出示例:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
Private-Key: (256 bit)
priv:
    e3:71:94:bb:ab:b7:af:49:f3:5d:8a:4f:db:8e:37:
    80:3d:ab:db:09:95:5e:5d:21:11:02:15:d6:9a:fd:
    41:f2
pub:
    04:69:c7:22:a8:99:1e:f8:8e:d0:55:d6:82:2a:96:
    43:20:86:9d:01:d6:62:98:3d:a1:75:5e:ef:51:ff:
    28:b7:50:e0:bb:07:38:e7:06:da:b5:13:58:a2:3f:
    e3:d8:49:66:02:08:a6:eb:24:24:ed:41:d7:2c:c8:
    90:77:fd:fe:4a
ASN1 OID: prime256v1
NIST CURVE: P-256

签名与验签

对文件签名

1
2
3
4
5
# 生成测试文件
echo "Hello, ECDSA!" > message.txt

# 使用私钥签名(SHA-256 哈希)
openssl dgst -sha256 -sign ecdsa_private.pem -out message.sig message.txt

验证签名

1
2
# 使用公钥验证
openssl dgst -sha256 -verify ecdsa_public.pem -signature message.sig message.txt

验证成功输出:

1
Verified OK

使用私钥直接验证

也可以使用私钥进行验证(用于测试):

1
openssl dgst -sha256 -prverify ecdsa_private.pem -signature message.sig message.txt

签名原理简述

ECDSA 签名过程:

  1. 选择随机数 k:每次签名必须使用不同的随机数
  2. 计算点 (x, y) = k × G:G 是曲线上的基点
  3. 计算 r = x mod n:n 是曲线的阶
  4. 计算 s = k⁻¹(hash + d·r) mod n:d 是私钥,hash 是消息哈希
  5. 签名 = (r, s)

验签过程使用公钥验证 s 的正确性。

⚠️ 注意:签名时使用的随机数 k 必须保持机密且不可预测。2010 年索尼 PlayStation 3 签名密钥泄露事件就是因为随机数重用导致私钥被恢复。

查看支持的曲线

1
openssl ecparam -list_curves

常用曲线:

  • prime256v1 - NIST P-256,广泛使用
  • secp384r1 - NIST P-384
  • secp521r1 - NIST P-521
  • secp256k1 - 比特币使用的曲线

完整示例

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
# 1. 生成密钥
openssl genpkey -algorithm EC -pkeyopt ec_paramgen_curve:prime256v1 -out key.pem

# 2. 导出公钥
openssl pkey -in key.pem -pubout -out pubkey.pem

# 3. 签名
echo "要签名的数据" | openssl dgst -sha256 -sign key.pem -out sig.sig

# 4. 验签
openssl dgst -sha256 -verify pubkey.pem -signature sig.sig sig.sig

小结

  • ECDSA 使用椭圆曲线密码学,密钥短、效率高
  • 主流TLS证书多使用 P-256 或 P-384 曲线
  • 签名需要安全的随机数生成器
  • OpenSSL 支持完整的 ECDSA 密钥生成、签名、验签操作

参考来源