Linux

OpenSSL 指令產生、驗證 ECDSA 橢圓曲線數位簽章教學與範例

介紹如何使用 OpenSSL 指令產生橢圓曲線加密金鑰,以 ECDSA 對檔案進行數位簽章,並驗證簽章有效性。

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

OpenSSL 指令實作 Ed25519

Ed25519 是一種使用 SHA-512 與 Curve25519 的 EdDSA 數位簽章演算法,然而 Ed25519 並不屬於標準的橢圓曲線,所以在 OpenSSL 中的指令與標準的橢圓曲線不同,不能以 ecparamsec 指令來進行 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
Share
Published by
Office Guide

Recent Posts

Python 使用 PyAutoGUI 自動操作滑鼠與鍵盤

本篇介紹如何在 Python ...

1 年 ago

Ubuntu Linux 以 WireGuard 架設 VPN 伺服器教學與範例

本篇介紹如何在 Ubuntu ...

1 年 ago

Linux 網路設定 ip 指令用法教學與範例

本篇介紹如何在 Linux 系...

1 年 ago

Linux 以 Cryptsetup、LUKS 加密 USB 隨身碟教學與範例

介紹如何在 Linux 系統中...

1 年 ago