CryptoCorner OpenSSL

Full working ECDSA signature with OpenSSL

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:

  1. Select a supported ECC curve
  2. Generate a private key (including the public key)
  3. Extract the public key
  4. Convert the ECC public key in DER and PEM format
  5. View the public key content
  6. Generate a hash
  7. Create a signature using the private key and the hash
  8. View the content of the signature
  9. 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

2 Gedanken zu „Full working ECDSA signature with OpenSSL“

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert