3

Recently, I've worked on setting certificate pinning for our mobile app. I'm using the hash of the Subject Public Key Information (SPKI) for the pinning. Now, I was under the impression that SPKI will be the same if I'll create another certificate from the same private key. So I tried it out - I created a private key using SSL and a matching CSR. Now, I signed this CSR twice using different private keys, and to my surprise - the SPKI (and the pin hash) was not the same. Is that the expected behavior? Or is it something I'm missing? Is the PKI in the certificate also signed?

Those are the openssl command I've used:

To generate a CSR:

openssl req -new -sha256 -key private.key -out private.csr

To generate CA private key:

openssl genrsa -des3 -out ca.key 2048

To sign the CSR:

openssl x509 -req -days 365 -in private.csr -signkey ca.key -out test.crt

This is the beginning of the SPKI from the first certificate:

BA 86 D3 0E E8 CC F3 C0 A2 B9 1E 8B BA 45 80 11 EF 13 CB 4F 76 CE A8 6A

And this is the beginning of the SPKI from the second certificate:

CC 96 B3 AB EA 0D FC 66 91 D8 E2 50 2B A7 8F 63 91 4C 7E 10 A3 48 1E 9F

To compute the hashes, I used the simplest way - imported the certificates to the mac keychain, and open them: certificate details

I also used this python script from TrustKit to get the certificate pinning hash, and it also was different.

1 Answers1

4

To sign the CSR:

 openssl x509 -req -days 365 -in private.csr -signkey ca.key -out test.crt

From man x509:

-signkey filename
... If the input is a certificate request then a self signed certificate is created using the supplied private key using the subject name in the request

In other words: you are creating a self signed certificate with ca.key as the key and not a certificate with private.key as key as you intended. Since you are using different ca.key you therefore get different keys inside the generated certificate and thus different subject public key information.

What you need to do instead is to create a CA and use it to sign the CSR like this:

$ openssl req -x509 -newkey rsa:4096 -keyout c0.pem -out c0.pem -days 365
$ openssl x509 -req -days 365 -in private.csr -CA c0.pem -CAcreateserial -out test0.crt

If you do this with different CA but the same CSR you will see that all resulting certificates have the same subject public key information, using the key included in the CSR.

Steffen Ullrich
  • 184,332
  • 29
  • 363
  • 424
  • So when a CA will sign my certificate the SPKI field will be the same? – Omer Levi Hevroni Dec 21 '17 at 06:40
  • @OmerLeviHevroni: see updated answer. – Steffen Ullrich Dec 21 '17 at 06:45
  • I think the CA file was created incorrectly - I'm receiving the following error: `Expecting: TRUSTED CERTIFICATE`. And by looking in `c0.pem`, I noticed it is RSA private key - `-----BEGIN ENCRYPTED PRIVATE KEY-----`, and I'm not sure how to do the conversation from private key to trusted certificate file – Omer Levi Hevroni Dec 21 '17 at 12:22
  • @OmerLeviHevroni: you did not create any CA. You've only created a key for the CA but not a CA certificate. See my answer how to properly create the CA certificate. With this instructions I have the key and the certificate inside the same file (look for `-----BEGIN CERTIFICATE-----`) – Steffen Ullrich Dec 21 '17 at 12:25
  • Sorry, it was my mistake - while creating the `c0.pem` file, I did not fill any certificate related field. Now it is working as expected. Thank you! – Omer Levi Hevroni Dec 21 '17 at 14:10