Blog

Credhub keeps your credentials out of your configuration files. 

On a recent project, I was adding certificates and their private keys to a CredHub instance so that Concourse could retrieve them to configure and then deploy a Cloud Foundry foundation that would then use these certificates.    

To do this, I ran:

credhub set --name /path/to/certificate --certificate "$(cat certchain.pem)" --private "$(cat privatekey.pem)

However, the CredHub CLI gave me the following error:

The provided key format is not supported. Keys must be PEM-encoded PKCS#1 keys.

I did not immediately know how to fix this because the private keys had been provided to me by a separate team. I could not re-generate them and simply check the "Please give me a PKCS#1 key" option. I also wasn't sure what the difference is between PKCS#1 keys and whatever format my keys were in.

Thanks to this CredHub error, I now know that my keys were in PKCS#8 format. This blog will show how to convert between PKCS#1 and PKCS#8, and explain the difference.

What are PKCS#1 keys?

PKCS#1 keys are private keys of the form:

-----BEGIN RSA PRIVATE KEY-----
	<Key Payload>
-----END RSA PRIVATE KEY-----

PKCS#8 keys (which the ones I had been provided were) are of the form:

-----BEGIN PRIVATE KEY-----
	<Key Payload>
-----END PRIVATE KEY-----

The difference between these two key representations is that PKCS#1 specifies in its envelope (first and last line of the file) that it was generated using an RSA cipher, while PKCS#8 specifies the same information inside of the key payload.

As their numbers imply, PKCS#8 was released after PKCS#1 chronologically. Specifying the cipher in its payload instead of directly in the header allowed for flexibility and compatibility that was built upon in later formats, such as PKCS#12.

Converting PKCS#8 to PKCS#1

Now one might think, "Wow, I just need to add RSA to my PKCS#8 keys' envelopes and they'll become PKCS#1 keys??"

Not quite.

PKCS#8 includes the cipher information in its key payload, so a private key in PKCS#8 format has a completely different key payload than the equivalent key in PKCS#1 format. Convert your keys and then look at their differing contents and you will see what I mean.

Converting a PKCS#8 key to a PKCS#1 key is incredibly easy. Simply run:

openssl rsa -in privateKeyPKCS8.pem -out privateKeyPKCS1.pem

Now my previous credhub set command works and properly sets the certificate and key:

credhub set --name /path/to/certificate --certificate "$(cat certchain.pem)" --private "$(cat privatekeyPKCS1.pem)

Converting PKCS#1 back to PKCS#8:

openssl pkcs8 -topk8 -inform PEM -outform PEM -in privateKeyPKCS1.pem -out privateKeyPKCS8.pem -nocrypt