3

I have seen other posts about converting PEM file to crt and key files like this one but it didn't work for me.

Using openssl x509 -outform der -in your-cert.pem -out your-cert.crt can generate a crt file but how to generate a corresponding key file? Assuming the key file has to be paired with the crt file?

There are posts like this one which suggests simply changing the file extension from .pem to .crt and .key will do the job. I tried changing the file extension but when using the crt and key files to start a https server in golang; it didn't work. The error is: found a certificate rather than a key in the PEM for the private key. This makes sense as I opened the PEM file which only contains ---BEGIN CERTIFICATE--- and END CERTIFICATE. Nothing about the key.

Also tried openssl pkey -in mypemFile.pem -out foo.key and openssl rsa -in mypemFile.pem -out foo.key; both got error: Expecting: ANY PRIVATE KEY

My situation is I need to create a https server using Golang, which would require a crt and key file to start a HTTPS server e.g. err := s.ListenAndServeTLS("../../mycert.crt", "../../mykey.key"), but I was given a PEM file from the company security team hence I want to convert the PEM file into crt and key files.

Jcs
  • 13,279
  • 5
  • 53
  • 70
dragonfly02
  • 3,403
  • 32
  • 55
  • Does this answer your question? [Convert .pem to .crt and .key](https://stackoverflow.com/questions/13732826/convert-pem-to-crt-and-key) – jub0bs Mar 13 '23 at 09:20
  • @jub0bs it doesn't say anything about how to generate a key file. – dragonfly02 Mar 13 '23 at 09:26
  • 1
    Before doing anything with tools you might want to learn more about how cryptography works and the relationship between certificate (basically a public key) and its associated private key. Also, extensions are irrelevant, computers do not care. Certificates (and private keys) are either in "binary" format called DER or more often for easier interoperability encoded in base64 to be called PEM. File names and extensions do not count, only the content counts. – Patrick Mevzek Mar 13 '23 at 17:26

1 Answers1

3

The most important thing here is: it is not possible to recover the private key from the certificate.

When running a HTTPS server you need 2 objects : A private key and a certificate chain (i.e. the server certificate and an optional list of signing certification authorities certificates).

Here are the steps you have to follow:

  1. Generate a private key pair: openssl genrsa -out private.pem 2048 This command generates a 2048-bits RSA private key in PEM format, i.e. with -----BEGIN RSA PRIVATE KEY----- header and -----END RSA PRIVATE KEY----- footer

  2. Extract the public key from the private key: openssl rsa -in private.pem -outform PEM -pubout -out public.pem This commands extracts the public key from the private key in PEM format i.e. with -----BEGIN PUBLIC KEY----- header and -----END PUBLIC KEY----- footer

  3. Create a certificate from the public key. This process to follow for this step totally depends on your certificate authority. However for testing purpose only you can generate a self-signed certificate.

  • Generate a Certificate Signature Request (CSR): openssl req -key private.pem -new -out mycert.csr. This command generates a mycert.csr file. Answer the question according to what you want to find in your certificate.

  • Self-sign that CSR: openssl x509 -signkey private.pem -in mycert.csr -req -days 365 -out mycert.pem. This command generates the certificate in the mycert.pem file in PEM format.

Then you can now start your server by providing the private.pem and mycert.pem files.

Note that if your framework does not support the PEM format for the private key you can convert it to other formats:

  • PKCS#1: openssl rsa -inform pem -in private.pem -outform der -out private.key
  • PKCS#8: openssl pkcs8 -topk8 -inform PEM -outform DER -in private.pem -out private.pk8 -nocrypt
Jcs
  • 13,279
  • 5
  • 53
  • 70
  • have to up vote before even trying it; as it sounds totally promising! Thank you. – dragonfly02 Mar 13 '23 at 10:44
  • So `mykey.pem` and `mykey.key`, and `mycert.crt` and `mycert.pem` are equivalent just different format? – dragonfly02 Mar 13 '23 at 10:45
  • 1
    @dragonfly02, yes, exactly. PEM encoding is pretty much just base64 encoding with line breaks, leading and trailing lines indicating the type of encoded object, and an optional header for metadata. Take a look at [the source code](https://cs.opensource.google/go/go/+/refs/tags/go1.20.2:src/encoding/pem/pem.go;l=240). It's really simple. – Peter Mar 13 '23 at 10:55
  • (1) in 3.0 up (since 2021) `genrsa` by default writes PKCS8 formats -- `BEGIN/END PRIVATE KEY` if you don't specify encryption or `BEGIN/END ENCRYPTED PRIVATE KEY` if you do -- and for PKCS1 you need `-traditional` (2) step 2 is unnecessary; the public key by itself is useless (3) step 3 can be done in one command: `openssl req -new -x509 -key privkey.pem -days 365 -out cert.pem [other options like -subj]` (4) in fact step 1 _and_ 3 can all be done in one command by changing `-new -key file` to `-newkey rsa:2048 -keyout file [-nodes]` – dave_thompson_085 Mar 13 '23 at 11:40
  • Sorry but how do I use the given PEM file? I assume I have to use it as it's provided by the company security team. I mean if I generate my own private key and crt files; not sure whether it will work when calling the internal APIs. – dragonfly02 Mar 13 '23 at 13:07
  • @dragonfly02 In that case you should ask your security team both files: the certificate (or probably the certificate chain) and the private key. You need both to setup the TLS layer in your server – Jcs Mar 13 '23 at 15:24
  • Thanks to all the comments and answer! – dragonfly02 Mar 14 '23 at 00:27