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...