Digital Signature With OpenSSL

Digital Signatures are used in an agreements, authorisations, contracts, and obviously a huge part of blockchain and crypto. Here is an example of creating an agreement, signing, and verifying using OpenSSL.

Lets create a document, which needs an agreement (signature):

echo I, Bob, promise to pay Mark £1000 by 1/1/2020 > contract.txt

For this example, we need to generate a private key, which will become our identity:

openssl genpkey -algorithm RSA -out private_key.pem -pkeyopt rsa_keygen_bits:2048

Now we need to generate the corresponding public key from the private key:

openssl pkey -in private_key.pem -pubout -out public_key.pem

Digitally sign the document (contract.txt):

openssl dgst -sha256 -sign private_key.pem -out signature.sign contract.txt

The signature.sign (arbitrary name) is a binary file. To verify the this signature using our public key:

openssl dgst -sha256 -verify public_key.pem -signature signature.sign contract.txt

This outputs:

Verified OK

Full script:

echo I, Bob, promise to pay Mark £1000 by 1/1/2020 > contract.txt
openssl genpkey -algorithm RSA -out private_key.pem -pkeyopt rsa_keygen_bits:2048
openssl pkey -in private_key.pem -pubout -out public_key.pem
openssl dgst -sha256 -sign private_key.pem -out signature contract.txt
openssl dgst -sha256 -verify public_key.pem -signature signature contract.txt

Using Hex

You can also output the signature as a hex string:

openssl dgst -sha256 -hex -sign private_key.pem -out signature.signed contract.txt

Which would give us the following:

RSA-SHA256(contract.txt)= a95d90f33226b85c82851ded024015848bdd21ef0e8347820ea50e03b8c3eaa54369efdacfa16a56586addf62d42ee8c2d44740a4906797e8180240700638f6c729f8f1ce9aec8749ad39ca8ae585e073585f0262c1832d1380f69b9be5808bdd8253413d625852d1c3fdefe51dc321ab79f7773f7b066c68264d730f4a4a8ee7fd8ecc90f17a8702f6b666f5527b545015173e7429fc056382369c03c061eca1f39e986ce62302c0e19e6627d37dee2215109692283eb1c4f39308de80dd973172614b371d6eb305e9858459b42141f1c3dff1af8e609e10df646f602098058c0fcc287d11c81584b3242cfaab3834074be1ac4fa49815c8995353e1a719cc7

Open ssl won't verify this file as it has meta data included, i.e. the hashing algorithm and signed file name. Instead you have to verify the hex hash using xxd which creates a hexdump reverses hex to binary:

echo a95d90f33226b85c82851ded024015848bdd21ef0e8347820ea50e03b8c3eaa54369efdacfa16a56586addf62d42ee8c2d44740a4906797e8180240700638f6c729f8f1ce9aec8749ad39ca8ae585e073585f0262c1832d1380f69b9be5808bdd8253413d625852d1c3fdefe51dc321ab79f7773f7b066c68264d730f4a4a8ee7fd8ecc90f17a8702f6b666f5527b545015173e7429fc056382369c03c061eca1f39e986ce62302c0e19e6627d37dee2215109692283eb1c4f39308de80dd973172614b371d6eb305e9858459b42141f1c3dff1af8e609e10df646f602098058c0fcc287d11c81584b3242cfaab3834074be1ac4fa49815c8995353e1a719cc7 | xxd -r -p > signature.binary

Then verify this binary file as before:

openssl dgst -sha256 -verify public_key.pem -signature signature.binary contract.txt