Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Decrypt with the public key using openssl in commandline

I want to 'manually' compare a digest/hash of a message with the decrypted signature value on this digest.

For this, I want to decrypt the signature value (the signed digest) of the message with the public key that belongs to the private key the digest was signed with in the first place.

I have the following items:

  • The digest value in base64 of the message (calculated with SHA256)
  • The signature value on the digest in base64 that has been signed with the private key (using SHA256 with RSA Encryption)
  • The public key in .pem format belonging to the private key
  • I have the actual message (it is in XML containing multiple signatures on different sections of the document). I already verified the signatures using the XML security library. I'm interested in only decrypting the signature value with the public key.

I'm kind of stuck of how I can achieve this using openssl.

I'm trying variations on the commands described here and here, however I'm kind of lost.

I suppose I should convert the signature from base64 value to octet using:

base64 --d sigfile > sigfile_octet?

Then I'm using the command:

openssl rsautl -inkey pubkey.pem -pubin -in sigfile_octet

Does this give me the decrypted signature value in octet? What are the next steps I need to perform to compare it with the base64 digest?

p.s. I already verified the signature using Aleksey's XML security library, so I know the digest should match the decrypted signature value.

Your help would be very much appreciated!!

Kind regards,

Diederik

like image 807
Diederik Avatar asked Sep 25 '22 07:09

Diederik


1 Answers

Use the dgst command, not rsautl:

openssl dgst -verify pubkey.pem -signature sigfile_octet message.txt

Here, message.txt is the message that you are trying to verify.


You can use rsautl to "decrypt" the signature, getting access to the raw verification data:

openssl rsautl -verify -inkey pubkey.pem -pubin -in sigfile_octet

This will yield the signature's DER-encoded ASN.1 structure. That's a sequence containing the algorithm identifier of the hash algorithm that was used, followed by the hash itself. If you want OpenSSL to print human-readable view of this structure, you can add the -asn1parse option to the the rsautl command. That looks something like this:

    0:d=0  hl=2 l=  49 cons: SEQUENCE          
    2:d=1  hl=2 l=  13 cons:  SEQUENCE          
    4:d=2  hl=2 l=   9 prim:   OBJECT            :sha256
   15:d=2  hl=2 l=   0 prim:   NULL              
   17:d=1  hl=2 l=  32 prim:  OCTET STRING      
      0000 - c9 8c 24 b6 77 ef f4 48-60 af ea 6f 49 3b ba ec   ..$.w..H`..oI;..
      0010 - 5b b1 c4 cb b2 09 c6 fc-2b bb 47 f6 6f f2 ad 31   [.......+.G.o..1

If you want to extract just the hash, instead of using the -asn1parse option, you can pipe it to the asn1parse command, which gives you the ability to extract elements from the structure.

When you say that you have "the signature value on the digest", I assume that what you have is a real signature with this structure, and not just the raw hash, which was signed with the private key. If that's not the case, you can post some example output.

like image 152
erickson Avatar answered Oct 03 '22 01:10

erickson