1

I've made a CSR (Certificate Signing Request) in order to better understand how a PKI could be made and how it works. Using the following commands

openssl req -new -newkey rsa:1024 -nodes -out ca.csr -keyout ca.key
openssl req -text -noout -verify -in ca.csr

I obtain the following output

Certificate Request:
    Data:
        Version: 1 (0x0)
        Subject: C = ca, ST = Some-State, O = Internet Widgits Pty Ltd
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                RSA Public-Key: (1024 bit)
                Modulus:
                    00:c2:ac:2f:7b:17:93:1c:39:07:aa:cf:8d:fd:b7:
                    2e:f4:90:76:16:d8:cf:cb:1b:02:ec:56:3d:ff:5e:
                    a2:fb:9e:8b:af:9b:3b:f8:27:4e:82:39:aa:6d:90:
                    e6:52:71:16:0d:f4:e0:fe:eb:50:31:79:3d:09:8a:
                    49:c0:b4:cb:1e:50:55:83:5f:81:58:46:03:1a:8a:
                    cf:22:56:2c:5f:30:ce:1f:cd:39:19:b4:4c:d4:8b:
                    c8:27:b2:34:62:31:e9:d2:b0:7c:f6:50:7a:12:f4:
                    1a:20:53:53:fb:46:ba:0b:b5:16:aa:ed:2d:0f:79:
                    eb:a2:7c:65:d1:3d:d1:74:87
                Exponent: 65537 (0x10001)
        Attributes:
            a0:00
    Signature Algorithm: sha256WithRSAEncryption
         4f:d7:d9:f5:fe:87:7c:fb:2d:e4:50:28:4d:b5:7a:5c:4f:87:
         f6:7a:83:59:2a:76:33:12:61:bf:c5:0d:5f:c8:41:d5:ec:b1:
         ed:01:21:98:b5:ab:3f:c0:12:78:aa:8e:c8:95:fd:e9:10:e7:
         69:8c:c3:e5:56:3d:f2:c8:b2:bb:5d:88:3f:5e:f8:f0:6b:e9:
         2c:ea:92:cb:90:60:3b:57:e7:09:6a:70:38:d1:43:0f:e6:72:
         31:99:a6:03:c4:3e:21:41:61:61:07:57:72:2a:41:ed:85:3c:
         d0:58:02:1c:81:ee:09:3c:39:02:21:fb:9b:25:4a:84:97:1b:
         c2:b6

What is not clear to me is the bytes after the "Signature Algorithm" field:

  1. How they are calculated?
  2. Which key is used?
  3. Which fields of ca.csr are signed?
  4. Is it possible to extract the signature and decode it (e.g. using openssl)?

After the CSR creation I use the following commands to create a self signed certificate

openssl x509 -trustout -signkey ca.key -req -in ca.csr -out ca.pem
openssl x509 -text -noout  -in ca.pem

Output below

Certificate:
    Data:
        Version: 1 (0x0)
        Serial Number:
            36:e9:c2:ae:ed:b2:a6:a2:00:7a:16:33:19:b8:57:a8:d8:c6:09:af
        Signature Algorithm: sha256WithRSAEncryption
        Issuer: C = ca, ST = Some-State, O = Internet Widgits Pty Ltd
        Validity
            Not Before: Jul  7 12:16:26 2020 GMT
            Not After : Aug  6 12:16:26 2020 GMT
        Subject: C = ca, ST = Some-State, O = Internet Widgits Pty Ltd
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                RSA Public-Key: (1024 bit)
                Modulus:
                    00:c2:ac:2f:7b:17:93:1c:39:07:aa:cf:8d:fd:b7:
                    2e:f4:90:76:16:d8:cf:cb:1b:02:ec:56:3d:ff:5e:
                    a2:fb:9e:8b:af:9b:3b:f8:27:4e:82:39:aa:6d:90:
                    e6:52:71:16:0d:f4:e0:fe:eb:50:31:79:3d:09:8a:
                    49:c0:b4:cb:1e:50:55:83:5f:81:58:46:03:1a:8a:
                    cf:22:56:2c:5f:30:ce:1f:cd:39:19:b4:4c:d4:8b:
                    c8:27:b2:34:62:31:e9:d2:b0:7c:f6:50:7a:12:f4:
                    1a:20:53:53:fb:46:ba:0b:b5:16:aa:ed:2d:0f:79:
                    eb:a2:7c:65:d1:3d:d1:74:87
                Exponent: 65537 (0x10001)
    Signature Algorithm: sha256WithRSAEncryption
         a4:91:01:17:9a:da:fe:45:5e:8d:08:1d:12:1f:63:22:81:b0:
         b5:cd:93:02:86:35:2e:e5:b4:17:6b:56:a2:f8:51:7b:98:8b:
         7d:ea:e1:16:0f:97:0c:e4:de:8f:1d:b1:d1:5b:97:aa:7a:07:
         58:db:cc:26:2f:21:f8:cc:f3:94:f9:9a:95:a3:ad:8e:53:a5:
         25:62:49:47:bf:a4:40:10:59:dd:f3:96:02:1c:d3:a9:04:82:
         ae:7d:c9:4a:27:7b:b3:41:7b:a0:35:54:79:48:dd:34:08:8a:
         dc:5e:dd:31:2c:67:9b:fb:84:b7:8c:81:9e:16:bf:4f:ab:43:
         e7:6f

In this case I have the same questions as above: why is the signature different from the one in the CSR?

Marc
  • 4,091
  • 1
  • 17
  • 23
Vilos
  • 13
  • 2

1 Answers1

3

RFC2986: PKCS #10: Certification Request Syntax Specification describes CSRs in detail. The overview answers most of your questions:

The process by which a certification request is constructed involves the following steps:

        1. A CertificationRequestInfo value containing a subject
           distinguished name, a subject public key, and optionally a
           set of attributes is constructed by an entity requesting
           certification.

        2. The CertificationRequestInfo value is signed with the subject
           entity's private key.  (See Section 4.2.)

        3. The CertificationRequestInfo value, a signature algorithm
           identifier, and the entity's signature are collected together
           into a CertificationRequest value, defined below.

So to take your questions one by one:

How are the bytes after the "Signature Algorithm" field calculated?

This is the signature itself, computed over the CSR data (in ASN.1 format, not the friendly text version shown by openssl) using the specified Signature Algorithm and the private key of the requester (here: Subject).

Which key is used?

The private key of the Subject is used to compute the signature. It can be verified using the public key (as found in the Subject Public Key Info field)

Which fields of ca.csr are signed?

All data in the CSR is signed. The data of course does not include the signature itself (that would be tricky).

Is it possible to extract the signature and decode it (e.g. using openssl)?

What you see is the hexadecimal representation of the signature bytes. Other than changing it into raw bytes, there is not much more to do with it.

However, you can verify it with openssl using the following:

$ openssl req -verify -in ca.csr -noout
verify OK

If I modify a single character in the CSR, the output becomes:

$ openssl req -verify -in ca.csr -noout
verify failure
140678320674112:error:0407008A:rsa routines:RSA_padding_check_PKCS1_type_1:invalid padding:../crypto/rsa/rsa_pk1.c:66:
140678320674112:error:04067072:rsa routines:rsa_ossl_public_decrypt:padding check failed:../crypto/rsa/rsa_ossl.c:588:
140678320674112:error:0D0C5006:asn1 encoding routines:ASN1_item_verify:EVP lib:../crypto/asn1/a_verify.c:170:

And for your final question about the certificate itself:

why is the signature different from the one in the CSR?

The signatures are different because the data itself is different (look at the fields listed in the CSR vs those in the certificate).

In normal workflows, the Subject and Issuer are separate entities with different keys (using the same key twice is just a convenient shortcut for self-signed certificates). The signature algorithm could also be different. All of these will yield different signatures.

Marc
  • 4,091
  • 1
  • 17
  • 23
  • _This is the signature itself, computed over the CSR data (in ASN.1 format, not the friendly text version shown by openssl) using the specified Signature Algorithm and the private key of the requester (here: Subject)._ OK: hence are you talking about the `ca.key` in the first command? – Vilos Jul 08 '20 at 08:47
  • _What you see is the hexadecimal representation of the signature bytes. Other than changing it into raw bytes, there is not much more to do with it._ OK: I don't know if a decrypted string like `0x00 0x01 0xFF .. 0xFF ASN1 HASH` could be seen with openssl – Vilos Jul 08 '20 at 08:53
  • _The certificate is signed using the private key of the Issuer, not the Subject. The fields are also different. So both the data and the key change (the signature algorithm can also change), resulting in a completely different signature._ Ok for the fields, but in this case we have a self signed certificate: the used key should be the same `ca.key` as above or not? – Vilos Jul 08 '20 at 08:53
  • 1) yes, `ca.key` is used to sign the CSR. This is the "subject private key". 2) there's not much else to see, a signature is just bytes 3) it's the same key only because you're reusing the key for both the CSR and the certificate. In general, the subject and issuer are two separate entities with different keys. I clarified the last section of my answer. – Marc Jul 08 '20 at 08:56
  • 1) OK 2) I coud extract the hash bytes from the signature. 3) OK 4) Why a signature is needed for CSR if it will be removed by the Issuer? the Issuer uses that signature in some way? – Vilos Jul 08 '20 at 09:04
  • 2) right, you'll need to do this yourself, I don't think `openssl` will output intermediate data in the signature verification. 4) the signature is needed to make sure that the CSR really is coming from the *Subject* with the specified public key and hasn't been tampered with. – Marc Jul 08 '20 at 09:16
  • 4) CA/issuer can ignore signature verification, right? Also - I have seen cases where CA edit/override subject field. In this case - signature is tempered anyway I believe. – Jack Jul 22 '21 at 04:20