There are many ressources that shows how to generate a RSA signature and perform a RSA signature verfication process. Nowadays, more and more developers are looking for ECC keys and ECDSA signature, as there are many reasons to consider elliptic curve cryptography (ECC):
- Key generation is much faster for ECC keys than for RSA keys
- Key operation for ECDSA signature is faster
- The EC key size is only 1/10 of comparable RSA keys, so smart cards and HSMs may hold more ECC than RSA keys in their secure memory
- The RSA algorithm my be compromized by quantum computer using Shor algorithm
- Modern applications like WireGuard and crypto-currencies rely on elliptic curve cryptography
In this walk through I will show the full process to perform a ECDSA signature:
- Select a supported ECC curve
- Generate a private key (including the public key)
- Extract the public key
- Convert the ECC public key in DER and PEM format
- View the public key content
- Generate a hash
- Create a signature using the private key and the hash
- View the content of the signature
- Verify the signature
This all is done with two commands only:
- OpenSSL (in my case version 1.1.1d)
- dumpasn1 (installed by Linux package dumpasn1)
OpenSSL ECDSA signature & verification
$ 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
$ openssl ecparam -name prime256v1 -genkey -noout -out prime256v1.key
$ openssl ec -in prime256v1.key -pubout -out prime256v1.pubkey.pem
read EC key
writing EC key
$ openssl ec -pubin -inform PEM -in prime256v1.pubkey.pem -outform DER -out prime256v1.pubkey
read EC key
writing EC key
$ dumpasn1 prime256v1.pubkey
0 89: SEQUENCE {
2 19: SEQUENCE {
4 7: OBJECT IDENTIFIER ecPublicKey (1 2 840 10045 2 1)
13 8: OBJECT IDENTIFIER prime256v1 (1 2 840 10045 3 1 7)
: }
23 66: BIT STRING
: 04 85 07 6D 3E 7B 9F C4 20 0F A5 83 B9 01 88 02
: 8C 6D A4 71 31 69 DC 24 64 89 44 AC 0B CE AD 63
: 09 87 B7 87 0C 72 94 5B 47 75 AA 71 C7 98 B0 20
: E5 01 81 69 43 0A 89 31 BD 37 D4 2A B9 B8 B7 D2
: A9
: }
0 warnings, 0 errors.
$ cat prime256v1.pubkey.pem
-----BEGIN PUBLIC KEY-----
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEhQdtPnufxCAPpYO5AYgCjG2kcTFp
3CRkiUSsC86tYwmHt4cMcpRbR3WqcceYsCDlAYFpQwqJMb031Cq5uLfSqQ==
-----END PUBLIC KEY-----
$ echo -n "My content for signing" |openssl dgst -sha256 -binary > hash256
$ hd hash256
00000000 3b f0 c4 55 a5 fa 03 4b f4 d5 dd 83 8b 5c 82 ee |;..U…K…....|
00000010 e0 73 cb c6 d0 b2 e8 52 4e 1c 36 9a d4 bd a8 6f |.s…..RN.6….o|
00000020
$ ls -al hash256
-rw-r--r-- 1 andreas powerusers 32 Jan 17 09:09 hash256
$ openssl pkeyutl -sign -inkey prime256v1.key -in hash256 > prime256v1.sig
$ openssl asn1parse -in prime256v1.sig -inform der
0:d=0 hl=2 l= 69 cons: SEQUENCE
2:d=1 hl=2 l= 33 prim: INTEGER :9B84FF851DAC2750370F059BEC09426214163CB9BFD3D859B842C308F46599B0
37:d=1 hl=2 l= 32 prim: INTEGER :251525426B1392518F1BA151A83D54BF097D6A8E33C6D80FB95D4E345CB6F506
$ openssl pkeyutl -in hash256 -inkey prime256v1.pubkey.pem -pubin -verify -sigfile prime256v1.sig
Signature Verified Successfully
In my other posts your find many more working examples and use cases for OpenSSL, OpenSC, PKCS#11 libraries, SoftHSM2.
Please share your experience as a comment! (German and English comments are welcome)
Related Posts
- How to sign data with OpenSSL on an HSM
- First Steps with OpenSSL for signature and encryption
- Full working ECDSA signature with OpenSSL
- SoftHSM2: What crypto mechanisms and ciphers are supported?
- Simple start with Yubico PKCS#11 library
- Export a RSA / ECC public key with OpenSC pkcs11-tool
- SoftHSM2 view slot info and objects on a specific slot
- Generate RSA, ECC and AES keys with OpenSC pkcs11-tool
- Show slot and token info with OpenSC pkcs11-tool
- SoftHSM2 first steps to create slots
- Configuration of OpenSC pkcs11-tool
- S/MIME Zertifikat per OpenSSL erstellen
- EFS Schlüssel per OpenSSL erstellen

Hello, thanks for sharing.
dumpasn1 prime256v1.pubkey
is wrong.
should be:
dumpasn1 ecc.eccnist14.pubkey
same for
cat prime256v1.pubkey.pem
Thanks a lot for your corrections. I updated the Linux commands accordingly.