Decrypt with the public key using openssl in commandline
Asked Answered
B

3

7

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

Beckman answered 23/2, 2016 at 17:5 Comment(0)
F
5

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.

Frankish answered 23/2, 2016 at 17:29 Comment(5)
It's unclear to me if the message is actually available, it doesn't say so in the question anyway. Diederik, could you indicate if this is the case (in the question please).Spindrift
Hi erickson, thank you for your anwser, however I'm not looking for an true/false answer regarding the validity of the signature. Is there more information I can attain from dgst command? I actually want to see the decrypted value of the signature value. @MaartenBodewes, yes I have the actual message, however I was already able to verify the signatures (it has multiple signatures on different sections of the message).Beckman
@Beckman "The message" is also a technical term for the input of the digest / signature algorithm. How you parse your specific (XML) messages is up to you. But OK, you specified that you want to perform textbook RSA decryption (or, actually, just modular exponentiation and PKCS#1 unpadding) with the public key. Right.Spindrift
@MaartenBodewes Ok thank you for the elaboration. After several steps I can successfully calculate the digest manually on the raw xml message ('using openssl dgst -sha256 message'). But yes! I'm actually looking for the textbook RSA decryption :)Beckman
@Beckman Please check out my update and let me know if it addresses your question.Frankish
C
0

Openssl CLI can achieve "decrypting with the public key" via the rsautl subcommand like so:

openssl rsautl -verify -inkey public_key.pem -pubin -in data.sig -raw -hexdump

Unlike the answer by @erickson this uses -raw to show the raw bytes of the decrypted ciphertext (signature) before padding is stripped, and -hexdump is added so it prints nicely to the terminal.

Clein answered 25/10, 2022 at 16:8 Comment(0)
S
0

As an update to other answers, now that openssl says it has deprecated its rsautl command, here is a current way to view the decrypted bytes of the signature:

openssl pkeyutl -verifyrecover -pubin -inkey pubkey.pem -in sigfile_octet -pkeyopt rsa_padding_mode:none -hexdump

Explanation:

  • pkeyutl (public key utilities): the command recommended for replacement of rsautl
  • -verifyrecover means you want to do verification 'manually' by looking at the recovered (decrypted) signature
  • -pubin -inkey pubkey.pem is the public key you're supplying for the decryption
  • -in sigfile_octet is the binary blob you want to decrypt
  • -pkeyopt rsa_padding_mode:none tells openssl to leave the padding in that was added when the hash was encrypted. If you omit this, the command doesn't output the padding (which usually consists of bytes 0x00 01, a lot of 0xFF, and another 0x00)
  • -hexdump puts the output on screen in a hexadecimal dump; alternatives are >file to save it or | program to open it in program.
Sheridansherie answered 21/6 at 14:49 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.