This article shows practical examples of how to generate and verify Elliptic curve (ECDSA) signatures using OpenSSL.

Step 1. Create private and public EC keys

$ openssl ecparam -name secp384r1 -genkey -noout -out private.key
$ cat private.key
-----BEGIN EC PRIVATE KEY-----
MIGkAgEBBDBvTmuYU1i6O5cHto+X1ffEvlPYZXhuij0xGrbM6P/vE7MZ+4OvmqMp
2seXWkn9nXugBwYFK4EEACKhZANiAASxtVEIv0o+2PT2xFTW0/4Kpsfg4viCR2EL
PNV7zioyICFb1JS5MZfrKyEAVrRmgWM3iWElS4ZQm7XH2cFB5eetWai30zNsXHZX
TcWVC9aO2MBjlLkIfhZQ1/64XMo/yS8=
-----END EC PRIVATE KEY-----
$ openssl ec -in private.key -pubout -out public.pem
read EC key
writing EC key
$ cat public.pem 
-----BEGIN PUBLIC KEY-----
MHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEsbVRCL9KPtj09sRU1tP+CqbH4OL4gkdh
CzzVe84qMiAhW9SUuTGX6yshAFa0ZoFjN4lhJUuGUJu1x9nBQeXnrVmot9MzbFx2
V03FlQvWjtjAY5S5CH4WUNf+uFzKP8kv
-----END PUBLIC KEY-----

Assuming we want to sign data in test.txt then we need to create hash and sign the hash.

In many cases we have digest value that need to be signed. Lets take sha256 hash “53edc760b7a66e1f4d8b0c5715725ee447b79c02f7759c52ad3d36eadd29c10a” and put it into the hash.hex file. Next we convert it to binay and sign.

$ xxd -r -p hash.hex > hash.bin
$ openssl pkeyutl -sign -inkey private.key -in hash.bin > signature.bin

EC signature consists of 2 numbers R and S. This is how the ASN.1 structure looks like

$ openssl asn1parse -in signature.bin -inform der
    0:d=0  hl=2 l= 100 cons: SEQUENCE          
    2:d=1  hl=2 l=  48 prim: INTEGER           :2DA42D92389E990E5DD7AFDFB8AB249D4564672574C85B3AD72CF37220CCDE4134F3040F4006941638C86300E31857F2
   52:d=1  hl=2 l=  48 prim: INTEGER           :1C5E2E56751CFF574E61B9842624A01B5AE084257DBF73E77AC5C80EBD54835F9139F8A6249CFB499D96D04CEBA4078D

Lets verify the signature hash

openssl pkeyutl -in hash.bin -inkey public.pem -pubin -verify -sigfile signature.bin

There is also one liner that takes file contents, hashes it and then signs.

$ openssl dgst -sha256 -sign private.key data.txt > signature.bin

To verify the signature we need to use the public key and following command

$ openssl dgst -sha256 -verify public.pem -signature signature.bin data.txt 
Verified OK

More info about elliptic curve and openssl from https://wiki.openssl.org/index.php/Command_Line_Elliptic_Curve_Operations

Extra 1. List of possible EC curves

$ 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
GDPR Badge BVCER ISO 27001 eIDAS eID Easy Google for Startups