openssl genrsa -out test1 2048
openssl req -new -key test1 -subj "/CN=foo" -out foo.csr
openssl req -in foo.csr -text
It Contains the public key of the keypair i have generated
Public Key Algorithm: rsaEncryption
Public-Key: (2048 bit)
Modulus:
00:ca:c5:29:98:08:05:30:30:03:08:eb:23:c2:af:
3e:2e:2d:dc:11:96:cb:2f:d1:1f:7f:41:a4:00:13:
8a:ee:4b:36:5b:f2:c1:d1:0f:8b:27:11:34:08:bd:
4d:df:7e:6d:7a:d7:f9:dd:ea:62:ad:fa:8f:8c:eb:
47:5f:55:82:2c:13:c2:11:41:12:b9:87:0b:3d:08:
86:1b:ad:71:16:89:1c:fa:07:4a:86:8f:80:a9:99:
37:f7:e2:d4:d3:d8:b2:5f:7f:c9:05:51:73:f0:c8:
59:ec:c3:09:a2:03:a5:6e:ec:8b:d9:9c:11:de:d3:
df:55:a5:3f:0c:36:d6:93:8a:70:a0:b9:61:cd:c9:
4a:09:ad:f7:3e:fd:ce:6f:5c:bb:00:69:e9:3b:3d:
85:3b:01:1d:8f:6a:a7:d4:61:f9:b5:07:1e:90:ed:
ab:3b:41:cc:db:e8:a0:e7:88:b7:77:35:66:30:b7:
a6:cd:ea:d6:12:f5:ef:82:63:e9:46:29:2e:7c:10:
0e:32:fd:04:2d:cd:62:0e:4b:74:46:f7:fd:f6:4a:
8d:fb:82:9d:37:11:50:ea:9f:f0:d6:64:2b:50:a4:
f0:18:6e:81:28:11:04:db:2a:0a:f7:b1:70:c5:78:
fe:ed:e3:55:2c:64:f4:a5:a0:96:f5:11:3a:27:2c:
5a:51
Exponent: 65537 (0x10001)
Subject attributes i have provided while creating the CSR
Subject: CN=foo
Digital Signature Information
Signature Algorithm: sha256WithRSAEncryption 92:b0:82:a5:aa:98:4a:62:5a:84:8a:15:5c:6f:48:dc:e3:ec: 7f:d5:04:e8:c1:47:55:3c:b3:57:84:16:ff:5a:0d:29:2c:16: f2:cc:0c:18:c3:1f:d5:e1:57:3a:dd:8b:b1:c6:92:c3:fe:cb: 2b:9d:7d:79:d5:64:eb:31:00:8b:5e:77:48:ce:66:6f:dd:7b: 71:41:f9:aa:6e:ea:ea:59:e0:cd:f8:db:a9:13:18:d2:2a:fc: 12:25:b3:01:44:0c:b1:02:f7:1a:0f:d0:07:04:1d:9f:6f:a1: 58:91:87:25:4a:d6:47:a6:b5:4e:3c:a1:fd:b6:6c:c3:96:16: c1:ab:00:d2:4c:95:ee:2c:01:2d:cf:0e:d0:62:1b:4f:0e:34: e3:e8:85:50:63:74:eb:1f:ac:95:30:d4:df:43:7f:58:11:90: 35:29:9d:85:94:dc:c8:c2:29:81:46:71:20:62:9c:9c:f8:ef: ed:bc:8b:e3:d5:41:b3:14:f7:43:c6:b2:74:c2:22:06:a2:af: 88:68:2e:67:c4:de:ed:61:37:41:d6:df:8a:76:7d:42:5d:98: d3:c9:19:8b:1d:26:73:92:95:0f:ba:c1:78:3a:55:87:e0:3e: 16:13:34:6e:21:13:b9:da:b8:66:f3:0a:ec:79:ae:1a:95:6c: 04:cf:b8:b5
Following are my doubts :
The data over which the signature is calculated is pretty much everything in the CSR except for the signature algorithm and signature. This is called the certificationRequestInfo
in RFC 2986.
The second question: how do we verify the signature?
The short answer: have openssl
do it for you.
The easiest way by far is to ask openssl
itself to verify it:
$ openssl genrsa -out test.key 2048
$ openssl req -new -key test.key -subj "/CN=foo" -out foo.csr
$ openssl req -in foo.csr -verify -noout
verify OK
Done!
The long (and tedious) answer: do it manually
Ok, so you really want to do it manually. Let's give it a shot.
Given the above, we first need to extract the desired information from the CSR. Dumping the ASN.1 structure, we get:
$ openssl asn1parse -i -in foo.csr
0:d=0 hl=4 l= 595 cons: SEQUENCE
4:d=1 hl=4 l= 315 cons: SEQUENCE
8:d=2 hl=2 l= 1 prim: INTEGER :00
11:d=2 hl=2 l= 14 cons: SEQUENCE
13:d=3 hl=2 l= 12 cons: SET
15:d=4 hl=2 l= 10 cons: SEQUENCE
17:d=5 hl=2 l= 3 prim: OBJECT :commonName
22:d=5 hl=2 l= 3 prim: UTF8STRING :foo
27:d=2 hl=4 l= 290 cons: SEQUENCE
31:d=3 hl=2 l= 13 cons: SEQUENCE
33:d=4 hl=2 l= 9 prim: OBJECT :rsaEncryption
44:d=4 hl=2 l= 0 prim: NULL
46:d=3 hl=4 l= 271 prim: BIT STRING
321:d=2 hl=2 l= 0 cons: cont [ 0 ]
323:d=1 hl=2 l= 13 cons: SEQUENCE
325:d=2 hl=2 l= 9 prim: OBJECT :sha256WithRSAEncryption
336:d=2 hl=2 l= 0 prim: NULL
338:d=1 hl=4 l= 257 prim: BIT STRING
This is a structured CertificationRequest defined by RFC 2986 as:
CertificationRequest ::= SEQUENCE {
certificationRequestInfo CertificationRequestInfo,
signatureAlgorithm AlgorithmIdentifier{{ SignatureAlgorithms }},
signature BIT STRING
}
The certificationRequestInfo
(see RFC for structure details) in DER-encoded ASN.1 format is signed using the algorithm described in signatureAlgorithm
and the private key to yield signature
.
Let's extract all the parts we need from the CSR. The strparse
value is the offset you want to export, this is the first number on each line in the output above.
# Extract the certificationRequestInfo (data to be signed)
$ openssl asn1parse -in foo.csr -strparse 4 -out info.der
# Extract the public key.
$ openssl req -pubkey -in foo.csr -noout -out pub.pem
# Alternatively, you can use:
$ openssl asn1parse -in foo.csr -strparse 27 -out tmp.der
$ openssl rsa -pubin -inform DER -in tmp.der -out pub.pem
# Extract the raw signature bytes:
$ openssl asn1parse -in foo.csr -strparse 338 -out sig.raw
0:d=0 hl=2 l= 70 cons: cont [ 3 ]
Error in encoding
139935063934272:error:0D07209B:asn1 encoding routines:ASN1_get_object:too long:../crypto/asn1/asn1_lib.c:91:
Ignore the error on the last one, this is because the extracted data is the raw signature bytes, it's not ASN.1 encoded. openssl
still happily wrote it out to the file.
We now have the following files:
info.der
: the DER-encoded data that was signedpub.pem
: the CSR requester's public keysig.raw
: the signature included in the CSRLet's verify the RSA signature (because that's what the signature algorithm says) using the public key and extract the original hash:
$ openssl rsautl -verify -pubin -inkey pub.pem -in sig.raw -out hash.der
$ openssl asn1parse -i -in hash.der -inform DER
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 [HEX DUMP]:192E0909DABC7454006628AA3F7FB009AFA62A17A44908CAE5E166E528DCDD11
It didn't fail, so we already know the public key is the one that matches the private key used to sign the data.
The last section, the long OCTET STRING
is the raw hash of the message as computed by the CSR requester:
192e0909dabc7454006628aa3f7fb009afa62a17a44908cae5e166e528dcdd11
Let's compute the sha256
hash (once again: because the signature algorithm tells us to) of the certificationRequestInfo
:
$ sha256sum info.der
192e0909dabc7454006628aa3f7fb009afa62a17a44908cae5e166e528dcdd11 info.der
Yay! The hash is equal to the one extracted from the signature.
The hashes match and the signature was signed by the private key corresponding to the public key listed in the CSR. This is a valid CSR.
Done! See, I said it would be tedious.