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.