介紹如何使用 OpenSSL 指令產生橢圓曲線加密金鑰,以 ECDSA 對檔案進行數位簽章,並驗證簽章有效性。
在實作 ECDSA 之前,要先決定採用的橢圓曲線,我們可以使用已下指令查詢 OpenSSL 中支援的橢圓曲線:
# 查詢 OpenSSL 支援的橢圓曲線 openssl ecparam -list_curves
secp112r1 : SECG/WTLS curve over a 112 bit prime field secp112r2 : SECG curve over a 112 bit prime field secp128r1 : SECG curve over a 128 bit prime field secp128r2 : SECG curve over a 128 bit prime field secp160k1 : SECG curve over a 160 bit prime field secp160r1 : SECG curve over a 160 bit prime field secp160r2 : SECG/WTLS curve over a 160 bit prime field secp192k1 : SECG curve over a 192 bit prime field secp224k1 : SECG curve over a 224 bit prime field secp224r1 : NIST/SECG curve over a 224 bit prime field secp256k1 : SECG curve over a 256 bit prime field secp384r1 : NIST/SECG curve over a 384 bit prime field secp521r1 : NIST/SECG curve over a 521 bit prime field prime192v1: NIST/X9.62/SECG curve over a 192 bit prime field prime192v2: X9.62 curve over a 192 bit prime field prime192v3: X9.62 curve over a 192 bit prime field prime239v1: X9.62 curve over a 239 bit prime field prime239v2: X9.62 curve over a 239 bit prime field prime239v3: X9.62 curve over a 239 bit prime field prime256v1: X9.62/SECG curve over a 256 bit prime field sect113r1 : SECG curve over a 113 bit binary field sect113r2 : SECG curve over a 113 bit binary field sect131r1 : SECG/WTLS curve over a 131 bit binary field sect131r2 : SECG curve over a 131 bit binary field sect163k1 : NIST/SECG/WTLS curve over a 163 bit binary field sect163r1 : SECG curve over a 163 bit binary field sect163r2 : NIST/SECG curve over a 163 bit binary field sect193r1 : SECG curve over a 193 bit binary field sect193r2 : SECG curve over a 193 bit binary field sect233k1 : NIST/SECG/WTLS curve over a 233 bit binary field sect233r1 : NIST/SECG/WTLS curve over a 233 bit binary field sect239k1 : SECG curve over a 239 bit binary field sect283k1 : NIST/SECG curve over a 283 bit binary field sect283r1 : NIST/SECG curve over a 283 bit binary field sect409k1 : NIST/SECG curve over a 409 bit binary field sect409r1 : NIST/SECG curve over a 409 bit binary field sect571k1 : NIST/SECG curve over a 571 bit binary field sect571r1 : NIST/SECG curve over a 571 bit binary field c2pnb163v1: X9.62 curve over a 163 bit binary field c2pnb163v2: X9.62 curve over a 163 bit binary field c2pnb163v3: X9.62 curve over a 163 bit binary field c2pnb176v1: X9.62 curve over a 176 bit binary field c2tnb191v1: X9.62 curve over a 191 bit binary field c2tnb191v2: X9.62 curve over a 191 bit binary field c2tnb191v3: X9.62 curve over a 191 bit binary field c2pnb208w1: X9.62 curve over a 208 bit binary field c2tnb239v1: X9.62 curve over a 239 bit binary field c2tnb239v2: X9.62 curve over a 239 bit binary field c2tnb239v3: X9.62 curve over a 239 bit binary field c2pnb272w1: X9.62 curve over a 272 bit binary field c2pnb304w1: X9.62 curve over a 304 bit binary field c2tnb359v1: X9.62 curve over a 359 bit binary field c2pnb368w1: X9.62 curve over a 368 bit binary field c2tnb431r1: X9.62 curve over a 431 bit binary field wap-wsg-idm-ecid-wtls1: WTLS curve over a 113 bit binary field wap-wsg-idm-ecid-wtls3: NIST/SECG/WTLS curve over a 163 bit binary field wap-wsg-idm-ecid-wtls4: SECG curve over a 113 bit binary field wap-wsg-idm-ecid-wtls5: X9.62 curve over a 163 bit binary field wap-wsg-idm-ecid-wtls6: SECG/WTLS curve over a 112 bit prime field wap-wsg-idm-ecid-wtls7: SECG/WTLS curve over a 160 bit prime field wap-wsg-idm-ecid-wtls8: WTLS curve over a 112 bit prime field wap-wsg-idm-ecid-wtls9: WTLS curve over a 160 bit prime field wap-wsg-idm-ecid-wtls10: NIST/SECG/WTLS curve over a 233 bit binary field wap-wsg-idm-ecid-wtls11: NIST/SECG/WTLS curve over a 233 bit binary field wap-wsg-idm-ecid-wtls12: WTLS curve over a 224 bit prime field Oakley-EC2N-3: IPSec/IKE/Oakley curve #3 over a 155 bit binary field. Not suitable for ECDSA. Questionable extension field! Oakley-EC2N-4: IPSec/IKE/Oakley curve #4 over a 185 bit binary field. Not suitable for ECDSA. Questionable extension field! brainpoolP160r1: RFC 5639 curve over a 160 bit prime field brainpoolP160t1: RFC 5639 curve over a 160 bit prime field brainpoolP192r1: RFC 5639 curve over a 192 bit prime field brainpoolP192t1: RFC 5639 curve over a 192 bit prime field brainpoolP224r1: RFC 5639 curve over a 224 bit prime field brainpoolP224t1: RFC 5639 curve over a 224 bit prime field brainpoolP256r1: RFC 5639 curve over a 256 bit prime field brainpoolP256t1: RFC 5639 curve over a 256 bit prime field brainpoolP320r1: RFC 5639 curve over a 320 bit prime field brainpoolP320t1: RFC 5639 curve over a 320 bit prime field brainpoolP384r1: RFC 5639 curve over a 384 bit prime field brainpoolP384t1: RFC 5639 curve over a 384 bit prime field brainpoolP512r1: RFC 5639 curve over a 512 bit prime field brainpoolP512t1: RFC 5639 curve over a 512 bit prime field SM2 : SM2 curve over a 256 bit prime field
我們可以使用以下指令查看特定橢圓曲線的實際參數:
# 顯示 secp384r1 橢圓曲線參數 openssl ecparam -name secp384r1 -param_enc explicit -text -noout
EC-Parameters: (384 bit) Field Type: prime-field Prime: 00:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff: ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff: ff:ff:fe:ff:ff:ff:ff:00:00:00:00:00:00:00:00: ff:ff:ff:ff A: 00:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff: ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff: ff:ff:fe:ff:ff:ff:ff:00:00:00:00:00:00:00:00: ff:ff:ff:fc B: 00:b3:31:2f:a7:e2:3e:e7:e4:98:8e:05:6b:e3:f8: 2d:19:18:1d:9c:6e:fe:81:41:12:03:14:08:8f:50: 13:87:5a:c6:56:39:8d:8a:2e:d1:9d:2a:85:c8:ed: d3:ec:2a:ef Generator (uncompressed): 04:aa:87:ca:22:be:8b:05:37:8e:b1:c7:1e:f3:20: ad:74:6e:1d:3b:62:8b:a7:9b:98:59:f7:41:e0:82: 54:2a:38:55:02:f2:5d:bf:55:29:6c:3a:54:5e:38: 72:76:0a:b7:36:17:de:4a:96:26:2c:6f:5d:9e:98: bf:92:92:dc:29:f8:f4:1d:bd:28:9a:14:7c:e9:da: 31:13:b5:f0:b8:c0:0a:60:b1:ce:1d:7e:81:9d:7a: 43:1d:7c:90:ea:0e:5f Order: 00:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff: ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:c7:63:4d:81:f4: 37:2d:df:58:1a:0d:b2:48:b0:a7:7a:ec:ec:19:6a: cc:c5:29:73 Cofactor: 1 (0x1) Seed: a3:35:92:6a:a3:19:a2:7a:1d:00:89:6a:67:73:a4: 82:7a:cd:ac:73
確認要採用的橢圓曲線之後,即可產生私鑰:
# 產生 secp384r1 橢圓曲線私鑰 openssl ecparam -name secp384r1 -genkey -noout -out secp384r1_priv_key.pem
執行之後,產生的私鑰會儲存於 secp384r1_priv_key.pem
這個檔案中,我們可以查看私鑰的內容:
# 查看私鑰內容
cat secp384r1_priv_key.pem
-----BEGIN EC PRIVATE KEY----- MIGkAgEBBDDVYtDwxB2k58dKbLeHBPbyurXK76gLw+QDS0ml/n5s+Z+4xktqJo/H vr5P1yC4rLKgBwYFK4EEACKhZANiAAT0L6ZlkX0YQG1kdbT/GPAJwCBtyc9pO6v+ +hf89b5/KjVPrAUcYF5mstMIo8B50ytOBTjbVXvaxmpIdzIBkjfvbDYfAban/cj8 WNtdPDqraRnkEcha6uQ6eIc7zvxQ2wM= -----END EC PRIVATE KEY-----
有了私鑰之後,再從這把私鑰產生對應的公鑰:
# 從私鑰產生對應的公鑰 openssl ec -in secp384r1_priv_key.pem -pubout -out secp384r1_pub_key.pem
read EC key writing EC key
查看產生的公鑰內容:
# 查看公鑰內容
cat secp384r1_pub_key.pem
-----BEGIN PUBLIC KEY----- MHYwEAYHKoZIzj0CAQYFK4EEACIDYgAE9C+mZZF9GEBtZHW0/xjwCcAgbcnPaTur /voX/PW+fyo1T6wFHGBeZrLTCKPAedMrTgU421V72sZqSHcyAZI372w2HwG2p/3I /FjbXTw6q2kZ5BHIWurkOniHO878UNsD -----END PUBLIC KEY-----
有了私鑰與公鑰之後,就可以使用私鑰對資料進行簽章。這裡我們使用 secp384r1_priv_key.pem
這一把私鑰搭配 SHA-256 演算法來產生 message.txt
這個檔案的數位簽章:
# 以私鑰搭配 SHA-256 產生數位簽章 openssl dgst -sha256 -sign secp384r1_priv_key.pem -out digest.sha256 message.txt
產生的數位簽章會存放在 digest.sha256
這個檔案中,後續可以使用對應的公鑰驗證該數位簽章的有效性:
# 以公鑰搭配 SHA-256 驗證數位簽章 openssl dgst -sha256 -verify secp384r1_pub_key.pem \ -signature digest.sha256 message.txt
Verified OK
如果 message.txt
這個檔案遭到竄改,則在驗證簽章時就會出現錯誤,例如:
# 以公鑰驗證數位簽章 openssl dgst -sha256 -verify secp384r1_pub_key.pem \ -signature digest.sha256 message_tempered.txt
Verification failure
Ed25519 是一種使用 SHA-512 與 Curve25519 的 EdDSA 數位簽章演算法,然而 Ed25519 並不屬於標準的橢圓曲線,所以在 OpenSSL 中的指令與標準的橢圓曲線不同,不能以 ecparams
或 ec
指令來進行 Ed25519 的操作,必須改用 genpkey
,以下是使用 OpenSSL 指令實作 Ed25519 的流程。
# 產生 Ed25519 私鑰 openssl genpkey -algorithm Ed25519 -out ed25519_priv_key.pem # 從私鑰產生對應的公鑰 openssl pkey -pubout -in ed25519_priv_key.pem -out ed25519_pub_key.pem
以 Ed25519 私鑰產生數位簽章:
# 以私鑰產生數位簽章 openssl pkeyutl -sign -inkey ed25519_priv_key.pem \ -rawin -in message.txt -out message.txt.sig
這裡產生的數位簽章儲存在 message.txt.sig
檔案中,接著我們可以用 Ed25519 公鑰驗證數位簽章的有效性:
# 以公鑰驗證數位簽章 openssl pkeyutl -verify -pubin -inkey ed25519_pub_key.pem \ -rawin -in message.txt -sigfile message.txt.sig
Signature Verified Successfully