23

I hope my question is not too general, but I find the topic of storing asymmetric keys very confusing..

Here's how I understand it: Using openSSL I can generate my RSA keys pair:

  • openssl genrsa -out private.pem gives me a PEM file which includes only private key
  • openssl rsa -in private.pem -outform PEM -pubout -out public.pem gives me a PEM file which contains a public key

So, after executing these 2 commands I have my RS-256 keys pair (is it the correct name? Keys are 2048bits as far as I know, so why RS-256, not RS-2048?).

  1. Can I consider the 2 files that I have (private.PEM + public.PEM) a certificate already?
  2. What is the content of CER, CRT or P12 files? I can't find any real examples of these files.
  3. How to generate CER, CRT or P12 from my 2 PEM files that I have?
  4. I saw some information that P12 file can be protected by a password - what is the reason to protect this file with a password - that password again has to be stored somewhere, already we store P12 file in a secure place where no one should have access to, right?
  5. I saw some example where 1 PEM file included both Public and Private keys. Isn't there a decided structure of PEM? Can I put there any keys I want?
  6. I saw also PEM file which had "-----BEGIN CERTIFICATE-----" and "-----END CERTIFICATE-----". What is that certificate? My 2 PEM files have: "-----BEGIN PUBLIC KEY-----...-----END PUBLIC KEY-----" and the other has: "-----BEGIN RSA PRIVATE KEY-----...-----END RSA PRIVATE KEY-----".
mnj
  • 379
  • 1
  • 2
  • 7

1 Answers1

37

openssl genrsa -out private.pem gives me a PEM file which includes only private key

Not really. In principle RSA can store just a privatekey with no publickey, but the RSAPrivateKey format used by OpenSSL (from PKCS1 aka RFCs 2313 2437 3447 8017) stores both. The formats used for other asymmetric algorithms (DSA, DH, ECC) also have this property, meaning you can always store only the privatekey file and still obtain the publickey whenever needed. GPG does the same thing; the public key information is always contained within the 'secret' key, as they call it for historical reasons. OpenSSH (mostly) uses the OpenSSL formats, so it isn't a useful observation.

openssl rsa -in private.pem -outform PEM -pubout -out public.pem gives me a PEM file which contains a public key

Which contains only the public key. And is pretty much useless because (1) it can be regenerated from the privatekey file and (2) most applications don't use just the publickey but instead a certificate.

So, after executing these 2 commands I have my RS-256 keys pair (is it the correct name? Keys are 2048bits as far as I know, so why RS-256, not RS-2048?).

Technically it's a keypair, but as above OpenSSL basically merges the concept of keypair with privatekey, and distinguishes only publickey -- which is the one that needs to be distinguished, because it's public.

Yes, crypto keys are almost always measured in bits. The scheme name RS256 (no hyphen) is used in JSON Web Signature (JWS) and JSON Web Token (JWT) to mean RSA signature (specifically the RSA signature scheme RSASSA-PKCS1-v1_5 defined by PKCS1) with SHA-256 for the hash. This is not related to the size of the RSA key and can be used with any (implemented) size; the example key for RS256 in RFC7517 is 1024-bit -- although RSA-1024 today does not provide an adequate margin of safety, and it has been prohibited by authorites like NIST and CABforum (and thus most web browsers) for several years. RSA signature (and also RSA encryption) is used in many many applications other than JWS/JWT.

Can I consider the 2 files that I have (private.PEM + public.PEM) a certificate already?

First a clarification: 'certificate' is a general concept used in many contexts. For crypto, the certificates of interest are usually public-key certificates which bind a public-key to an identity (or sometimes a role) with some related attributes, and the most common ones by far are the public-key certificates defined by X.509, a standard created in 1988 by then-CCITT (now-ITU-T) and since enhanced and made more useful, but not fundamentally different, by many standards organizations. The Internet standards for certificates are based on X.509 and called Public Key Infrastructure using X.509, abbreviated PKIX. X.509, like some other computer standards, represents its data using a generic syntax called Abstract Syntax Notation 1, abbreviated ASN.1.

With that said, NO. A public-key/X.509 certificate contains a publickey, but it is not merely a publickey. It contains a good deal of other information that is vital to the way it is used, although the publickey is arguably the most important single piece of information. A certificate is created for a publickey, normally packaged as a Certificate Signing Request aka CSR or just request, by an entity called a Certificate Authority or CA which digitally signs the certificate using the CA's key so that no one else can alter it, and thus any program using it can trust it. In principle anybody can act as a CA, and in particular the OpenSSL commandline program can perform the technical operations a CA does, like issuing certificates. However, in most situations the value and usefulness of a certificate depends on how well and widely the issuing CA is trusted, so the most successful CAs are the ones that have established themselves as trusted, such as Digicert-now-including-Symantec-formerly-Verisign, Comodo, GoDaddy, etc.

As a special case, it is possible to have a 'self-signed' certificate, which is signed using its own key instead of a CA's key. This certificate can't convey trust like one from a real CA, because it is NOT effectively protected against substitution, but it can be created even when you can't contact and/or pay a CA, and it can usually be processed, with manual approval or override, by programs that are designed to normally use or require a certificate.

What is the content of CER, CRT or P12 files? I can't find any real examples of these files.

CER and CRT are (both) commonly used as extensions for a file containing an X.509 certificate, and may be in either case depending on the filesystem. There are two common encodings used for the file contents: "DER", which is a binary encoding (Distinguished Encoding Rules) defined by ASN.1; and "PEM", which converts the binary DER to base64, broken into conveniently sized lines and with header and trailer lines added, which is more convenient for people, especially for things like cut-and-paste. PEM is so-named because this encoding was originally defined for Privacy Enhanced (e)Mail, a scheme which been superseded by other email and message technologies, but this format remains in use. These encodings look very different, but they contain exactly the same information (unless damaged), and many programs that deal with certificates can read both. PEM files written by OpenSSL often include 'comment' information before the header or after the trailer; programs should ignore this, but sometimes they get confused and you need to remove the extraneous information. On Windows, also be careful NOT to use 'UTF-8' format which usually adds a Byte Order Mark that is not visible on the display but interferes with a program reading the file.

Although PEM is widely used for certificates and many PEM files are certificates, be aware PEM is used for many other things as well. Don't assume a PEM file is a certificate; instead check the header line, which for this case conveniently says -----BEGIN CERTIFICATE----- or sometimes -----BEGIN X509 CERTIFICATE-----. See rfc7468 for much more detail on this.

P12 is commonly used to identify files in the PKCS12 aka PFX format, which is quite different. Although the PKCS12 standard supports a large number of options, it is normally used to contain a privatekey PLUS the corresponding certificate PLUS in most cases one or more 'chain' or 'intermediate' certificate(s) that are needed to form a trust chain to validate the end-entity certificate. In practice PKCS12 files are always binary, although there's no technical reason they couldn't be PEM-encoded or otherwise made more human-friendly.

How to generate CER, CRT or P12 from my 2 PEM files that I have?

To get a certificate you need to either use a CA (either an established one or a DIY one you create) or create a selfsigned certificate. There are probably hundreds of variations of each of these depending on what software (and CA if any) you use, but for OpenSSL and most CAs the usual procedure is:

  1. Create a CSR using openssl req -new -key privatekey [... other options] >csr

See the man page for req for details. If you want to use the certificate for SSL/TLS including HTTPS, make the 'Common Name' be the (or a) name by which the server will be accessed, which is normally its Fully Qualified Domain Name (FQDN). If you want to use the certificate for other applications, the necessary identity information depends on the application(s).

  1. For a real CA, submit the CSR to the CA (often on a webform, which PEM makes convenient) along with the proof of identity or other authorization, and possibly payment, they require.

You should receive in return a newly-issued 'end-entity' certificate (containing your publickey and identity) and usually one or two cert(s) containing publickey(s) and identity(ies) for intermediate CAs used to create the trust chain. These may be separate files (either DER or PEM) or a concatenation (PEM only) or a particular case of the PKCS7 standard (SignedData with no data or signatures only certificates) usually called P7B or P7C.

2'. Or, do this yourself. Create a CA key and cert (only once) and then use either openssl ca ... or openssl x509 -req -CA -CAkey ... to read the CSR and issue a cert under your own CA.

This cert will be usable only with systems and programs controlled by you yourself or people who implicitly trust you and are technically able to install your CA cert, which is typically a small group, sometimes an empty one. Also be careful not to give your CA cert and end-entity cert the same name, for example by accepting the defaults in req; if you do that, the resulting certs won't be usable anywhere.

  1. Use the cert, together with the privatekey and chain cert(s), as needed. This may involve combining them into a PKCS12, using openssl pkcs12 -export.

As noted above, you can create a self-signed cert instead of a CA-issued one. Replace steps 1 and 2/2' with the single step: openssl req -new -x509 -key privatekey ... >cert

Note the addition of the -x509 flag, and there are numerous additional options described on the man page. This has all the properties and limitations of a DIY CA, plus more: you (and/or your friends) can't just install the DIY CA cert once, but must install each end-entity cert separately and repeat the process anytime one of your certs must be replaced because it expires or any any relevant information changed.

I saw some information that P12 file can be protected by a password - what is the reason to protect this file with a password - that password again has to be stored somewhere, already we store P12 file in a secure place where no one should have access to, right?

The password doesn't necessarily have to be stored; programs can prompt for it when necessary (and the openssl program in particular does so). Although now often used for storage, PKCS12/PFX was originally intended for transferring a privatekey, with cert(s), from one system to another, a process that is very often not secure. Even for storage, systems and places you think are secure sometimes turn out not to be, and the defense-in-depth of encrypting the privatekey is worth it. But in some cases yes the password is just a small bit of extra work for no real benefit.

I saw some example where 1 PEM file included both Public and Private keys. Isn't there a decided structure of PEM? Can I put there any keys I want?

Whether more than one object can be read from, and thus usefully stored in, a single PEM file depends on the program doing the reading. OpenSSL in most (but not all) cases can handle this, so using such files with OpenSSL (and programs that call OpenSSL library) is moderately common; other programs and libraries may be different. As above, storing the publickey as such is almost never useful. Storing e.g. the privatekey and the certificate, or all the certificates in the chain, can be useful. Programs like Apache httpd and nginx support this (but do not require it).

I saw also PEM file which had "-----BEGIN CERTIFICATE-----" and "-----END CERTIFICATE-----". What is that certificate?

See above for certificates in general. If you want to know the details of a particular cert (the name of the key owner, called 'subject'; the public-key; the time period the cert is valid; the issuing CA and its serial number, etc) you can use openssl x509 -text <file or depending on your system usually several other programs are capable of displaying cert details. On Windows for .cer .crt you can just doubleclick a file (or name it in the 'run' dialog or a start command in CMD) and a dialog will pop up containing a Details tab.

dave_thompson_085
  • 9,759
  • 1
  • 24
  • 28
  • 2
    Wow, thanks for this great answer. I'll read it in detail and in case of additional questions, I'll put them here as comments. I'm really grateful for your time, your answer is really valuable. – mnj Apr 07 '18 at 12:46