0

I'm trying to learn PKI and I want to do a test to verify my understanding of digital certificates by comparing hash values... Let me explain.

As I understand it in laymens terms, if I have a publically signed digital certificate for a server, then the servers certificate will have a digital signature created by the CA attached within it. So when I browse to that server over https for example, my computer will verify the certificate by checking the chain of trust. So it grabs the digital certificate, decrypts it (using the public key of the CA) and reveals a hash value. This is compared to the hash value of the data that was signed, and if they match, then the certificate was signed by a trusted source.

So now the bit I want to try and emulate is manually verifying a digital signature I create on a computer using openssl. As such I did the following:

## Create a key pair
$ openssl genrsa -aes128 -passout pass:Test123 -out private.pem 4096
$ openssl rsa -in private.pem -passin pass:Test123 -pubout -out public.pem

Create a file as something to sign

$ touch filex $ echo "some data" > filex

Sign the file

$ openssl dgst -sha256 -sign private.pem -out data.txt.signature filex

Verify the signature

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

So this sort of confirms what I wanted (although there is no CA here). What I want do do is see the actual hash value it computed when it decrypts the digital signature, so I can run a sha256sum on my "filex" and compare the two. But I can't seem to find a way to do this. Can anyone help me with finding a way to achieve this?

UPDATE: Since someone posted a link to a similar previous question, I tried that method but I can't get it to work. I will therefore copy the steps I've done below:

First i grabbed the stackexchange.pem and the CA's E1.pem file from my browser on this site and downloaded it.

$ openssl asn1parse -i -in stackexchange.pem 
    0:d=0  hl=4 l= 947 cons: SEQUENCE          
    4:d=1  hl=4 l= 824 cons:  SEQUENCE          
    8:d=2  hl=2 l=   3 cons:   cont [ 0 ]        
   10:d=3  hl=2 l=   1 prim:    INTEGER           :02
   13:d=2  hl=2 l=  18 prim:   INTEGER           :035FE125AEA1239BD263714150F2D8EE3C0F
   33:d=2  hl=2 l=  10 cons:   SEQUENCE          
   35:d=3  hl=2 l=   8 prim:    OBJECT            :ecdsa-with-SHA384
   45:d=2  hl=2 l=  50 cons:   SEQUENCE          
   47:d=3  hl=2 l=  11 cons:    SET               
   49:d=4  hl=2 l=   9 cons:     SEQUENCE          
   51:d=5  hl=2 l=   3 prim:      OBJECT            :countryName
   56:d=5  hl=2 l=   2 prim:      PRINTABLESTRING   :US
   60:d=3  hl=2 l=  22 cons:    SET               
   62:d=4  hl=2 l=  20 cons:     SEQUENCE          
   64:d=5  hl=2 l=   3 prim:      OBJECT            :organizationName
   69:d=5  hl=2 l=  13 prim:      PRINTABLESTRING   :Let's Encrypt
   84:d=3  hl=2 l=  11 cons:    SET               
   86:d=4  hl=2 l=   9 cons:     SEQUENCE          
   88:d=5  hl=2 l=   3 prim:      OBJECT            :commonName
   93:d=5  hl=2 l=   2 prim:      PRINTABLESTRING   :E1
   97:d=2  hl=2 l=  30 cons:   SEQUENCE          
   99:d=3  hl=2 l=  13 prim:    UTCTIME           :231117014719Z
  114:d=3  hl=2 l=  13 prim:    UTCTIME           :240215014718Z
  129:d=2  hl=2 l=  28 cons:   SEQUENCE          
  131:d=3  hl=2 l=  26 cons:    SET               
  133:d=4  hl=2 l=  24 cons:     SEQUENCE          
  135:d=5  hl=2 l=   3 prim:      OBJECT            :commonName
  140:d=5  hl=2 l=  17 prim:      PRINTABLESTRING   :stackexchange.com
  159:d=2  hl=2 l=  89 cons:   SEQUENCE          
  161:d=3  hl=2 l=  19 cons:    SEQUENCE          
  163:d=4  hl=2 l=   7 prim:     OBJECT            :id-ecPublicKey
  172:d=4  hl=2 l=   8 prim:     OBJECT            :prime256v1
  182:d=3  hl=2 l=  66 prim:    BIT STRING        
  250:d=2  hl=4 l= 578 cons:   cont [ 3 ]        
  254:d=3  hl=4 l= 574 cons:    SEQUENCE          
  258:d=4  hl=2 l=  14 cons:     SEQUENCE          
  260:d=5  hl=2 l=   3 prim:      OBJECT            :X509v3 Key Usage
  265:d=5  hl=2 l=   1 prim:      BOOLEAN           :255
  268:d=5  hl=2 l=   4 prim:      OCTET STRING      [HEX DUMP]:03020780
  274:d=4  hl=2 l=  29 cons:     SEQUENCE          
  276:d=5  hl=2 l=   3 prim:      OBJECT            :X509v3 Extended Key Usage
  281:d=5  hl=2 l=  22 prim:      OCTET STRING      [HEX DUMP]:301406082B0601050507030106082B06010505070302
  305:d=4  hl=2 l=  12 cons:     SEQUENCE          
  307:d=5  hl=2 l=   3 prim:      OBJECT            :X509v3 Basic Constraints
  312:d=5  hl=2 l=   1 prim:      BOOLEAN           :255
  315:d=5  hl=2 l=   2 prim:      OCTET STRING      [HEX DUMP]:3000
  319:d=4  hl=2 l=  29 cons:     SEQUENCE          
  321:d=5  hl=2 l=   3 prim:      OBJECT            :X509v3 Subject Key Identifier
  326:d=5  hl=2 l=  22 prim:      OCTET STRING      [HEX DUMP]:0414ABB9D50E8357BF0921BC299E1B83B6ED2A1BB326
  350:d=4  hl=2 l=  31 cons:     SEQUENCE          
  352:d=5  hl=2 l=   3 prim:      OBJECT            :X509v3 Authority Key Identifier
  357:d=5  hl=2 l=  24 prim:      OCTET STRING      [HEX DUMP]:301680145AF3ED2BFC36C23779B95230EA546FCF55CB2EAC
  383:d=4  hl=2 l=  85 cons:     SEQUENCE          
  385:d=5  hl=2 l=   8 prim:      OBJECT            :Authority Information Access
  395:d=5  hl=2 l=  73 prim:      OCTET STRING      [HEX DUMP]:3047302106082B060105050730018615687474703A2F2F65312E6F2E6C656E63722E6F7267302206082B060105050730028616687474703A2F2F65312E692E6C656E63722E6F72672F
  470:d=4  hl=2 l=  75 cons:     SEQUENCE          
  472:d=5  hl=2 l=   3 prim:      OBJECT            :X509v3 Subject Alternative Name
  477:d=5  hl=2 l=  68 prim:      OCTET STRING      [HEX DUMP]:304282182A2E6D6574612E737461636B65786368616E67652E636F6D82132A2E737461636B65786368616E67652E636F6D8211737461636B65786368616E67652E636F6D
  547:d=4  hl=2 l=  19 cons:     SEQUENCE          
  549:d=5  hl=2 l=   3 prim:      OBJECT            :X509v3 Certificate Policies
  554:d=5  hl=2 l=  12 prim:      OCTET STRING      [HEX DUMP]:300A3008060667810C010201
  568:d=4  hl=4 l= 260 cons:     SEQUENCE          
  572:d=5  hl=2 l=  10 prim:      OBJECT            :CT Precertificate SCTs
  584:d=5  hl=3 l= 245 prim:      OCTET STRING      [HEX DUMP]:0481F200F000770048B0E36BDAA647340FE56A02FA9D30EB1C5201CB56DD2C81D9BBBFAB39D884730000018BDB2CF9BB0000040300483046022100D3057AB69D47FA324E26A59D5210029843F17CA8034FD70045A2F6514098434B022100A693797A5A0EE660AC1C4D904079FC367F921826980340F6ED9C5D580C63CFC7007500EECDD064D5DB1ACEC55CB79DB4CD13A23287467CBCECDEC351485946711FB59B0000018BDB2CF9D1000004030046304402206044A6FAE9C47837ABA50300BFC5C2EBBD33705697EB5C7DB40BDAAC4638E16D02205EB94A42B09FFDE5277C7A2B02BCA288EA859E114B71B4C41D022CC3FFB6D427
  832:d=1  hl=2 l=  10 cons:  SEQUENCE          
  834:d=2  hl=2 l=   8 prim:   OBJECT            :ecdsa-with-SHA384
  844:d=1  hl=2 l= 105 prim:  BIT STRING        

My markers are 4 and 844 (after 844 = sig)

Grab data to be signed, and leave in binary

$ openssl asn1parse -in stackexchange.pem -strparse 4 -out stackexchange.tbs

Grab the digital signature

$ openssl asn1parse -in stackexchange.pem -strparse 844 -out stackexchange.sig

Grab public key from the CA's pem file

$openssl x509 -in E1.pem -noout -pubkey > e1.pub

Check output

   $ openssl pkey -in e1.pub -pubin -text
-----BEGIN PUBLIC KEY-----
MHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEJFwtoir9HEumXZdzJzGssqBpYu9l6Kaw
8KxLn/8cC3AP05gvTfwPAJs38HQFVzKXLgXvKkMlo/tuNCcT9k9+adMCmV7rJEeS
wSSb5rEhj8EkgfxozB9pulj1GSL3dMYW
-----END PUBLIC KEY-----
Public-Key: (384 bit)
pub:
    04:24:5c:2d:a2:2a:fd:1c:4b:a6:5d:97:73:27:31:
    ac:b2:a0:69:62:ef:65:e8:a6:b0:f0:ac:4b:9f:ff:
    1c:0b:70:0f:d3:98:2f:4d:fc:0f:00:9b:37:f0:74:
    05:57:32:97:2e:05:ef:2a:43:25:a3:fb:6e:34:27:
    13:f6:4f:7e:69:d3:02:99:5e:eb:24:47:92:c1:24:
    9b:e6:b1:21:8f:c1:24:81:fc:68:cc:1f:69:ba:58:
    f5:19:22:f7:74:c6:16
ASN1 OID: secp384r1
NIST CURVE: P-384

Hash the to be signed fields into a binary

$ openssl sha384 <stackexchange.tbs -binary >hash

Now perform the manual verification

$ openssl pkeyutl -verify -in hash -sigfile stackexchange.sig -inkey e1.pub -pubin -pkeyopt digest:sha384
Signature Verified Successfully

Ah crap, I realised when trying to edit this post with an update about the method dave linked not working, that I made an error in my implementation of it. And as such when editing this post, I've actually given the exact answer I wanted rather than the problem with this update since I see it verifying successfully now.

I would still like to understand why @u1686_grawity thinks decryption isn't involved in verification, since I'm open to suggestions. However my update shows that I do a hash of all To-Be-Signed fields of the cert manually, and hash this into a file called "hash", and then grab the public certificate of the E1.pem (the CA for the original pem file) use this as as the decryption key as input and run that against the .sig file. Since both my hash result and the decrypted hash value match, it means the signature I extraced from the original pem file is absolutely verified by the CA and authentic. So I'm baffled as to why the likes of u1686_grawity and many others on the internet believe no decryption takes place...

  • Crossdupe https://security.stackexchange.com/questions/127095/manually-walking-through-the-signature-validation-of-a-certificate (disclosure: answer partly mine) – dave_thompson_085 Jan 02 '24 at 00:39
  • Forget the "...decrypts the digital signature" part, please. Functionally there is no encryption or decryption involved in validating digital signatures; signature validation is signature validation. (Even if the math happens to be similar for certain algorithms.) – u1686_grawity Jan 02 '24 at 06:02
  • @dave_thompson_085 thanks for this. This was what I was looking for, however the line with: $ openssl asn1parse -in wikipedia.pem -strparse 1554 -out wikipedia.sig appears to write 0 bytes to the output annoyingly (obviously after I adapted it to a more recent sig/test), so I'll try figure out why (if you know why let me know as it will save me time figuring it out). As for u1686_grawity, I believe you are wrong. The hash used in the sig is created via use of the private key, hence why dave's post shows a public key in use of the CA to decrypt the hashed data. Please elaborate ur answer. – john smith Jan 02 '24 at 11:15
  • 1
    That 1554 is the offset of the signature (or pedantically the BITSTRING containing the signature) for the particular cert shown in that post, but it is different for other certs; use the value for your particular cert. Also I do NOT show 'decrypting' the hash; I show verifying the signature using the verifier's hash. RSA signatures only can recover the hash -- it's wrong to call this decryption, see PKCS1 -- but other signatures like DSA ECDSA and now EdDSA (new since 2016) cannot. You need atsign to notify someone like @u1686_grawity . – dave_thompson_085 Jan 05 '24 at 08:02

0 Answers0