Table of Contents

Introduction
Definitions
Example Private & Public Keys
OpenSSH Public Keys
SSH-2 Public Keys
Examining OpenSSH Public Keys

Introduction

There is a lot of confusion and inaccurate information on the Internet about Key Pairs and Private/Public keys. This article will help explain what they are and how they are used in the cloud world. After reading this article, you should know exactly what key pairs, private keys, public keys, certificates, PKCS #1, PKCS #8, etc. really are and how to use each one in different scenarios.

In its simplest form, a key pair is just three numbers: Modulus, Private Exponent and Public Exponent. That’s it. These three numbers are all that is required to perform asymmetric encryption and decryption. The different types of files are just different ways of encoding these three numbers.

The beginning of this article will be very technical and boring. However, having a good understanding of the technical details will help you to understand how to securely and safely use private and public keys when managing your cloud resources. This article will become more interesting as we will create private and public key pairs for making secure logins into our cloud resources.

Mostly, you only need to learn about PKCS #1 PEM files. We use these files for private and public keys for SSH access to your cloud instances. If you also need to manage SSL certificates, then understanding the additional formats will be required.

Download Git Repository

I have published the files for this article on GitHub.

License: MIT License

Clone my repository to your system:

Definitions

Let’s start by defining some terms that I will use below. I would like to give credit to Wikipedia for these definitions.

Term Definition
PKI Public Key Cryptography. Public-key cryptography, or asymmetric cryptography, is any cryptographic system that uses pairs of keys: public keys which may be disseminated widely, and private keys which are known only to the owner. This accomplishes two functions: authentication, where the public key verifies that a holder of the paired private key sent the message, and encryption, where only the paired private key holder can decrypt the message encrypted with the public key.
PKCS In cryptography, PKCS stands for “Public Key Cryptography Standards”. These are a group of public-key cryptography standards devised and published by RSA Security Inc, starting in the early 1990s. The company published the standards to promote the use of the cryptography techniques to which they had patents, such as the RSA algorithm, the Schnorr signature algorithm and several others. Though not industry standards (because the company retained control over them), some of the standards in recent years have begun to move into the “standards-track” processes of relevant standards organizations such as the IETF and the PKIX working-group.
RSA RSA (Rivest-Shamir-Adleman) is one of the first public-key cryptosystems and is widely used for secure data transmission. In such a cryptosystem, the encryption key is public and it is different from the decryption key which is kept secret (private). In RSA, this asymmetry is based on the practical difficulty of the factorization of the product of two large prime numbers, the “factoring problem”. The acronym RSA is made of the initial letters of the surnames of Ron Rivest, Adi Shamir, and Leonard Adleman, who first publicly described the algorithm in 1978. Clifford Cocks, an English mathematician working for the British intelligence agency Government Communications Headquarters (GCHQ), had developed an equivalent system in 1973, but this was not declassified until 1997.

A user of RSA creates and then publishes a public key based on two large prime numbers, along with an auxiliary value. The prime numbers must be kept secret. Anyone can use the public key to encrypt a message, but with currently published methods, and if the public key is large enough, only someone with knowledge of the prime numbers can decode the message feasibly. Breaking RSA encryption is known as the RSA problem. Whether it is as difficult as the factoring problem remains an open question.

Private Key A Private Key is a secret key, used in Asymmetric Encryption. It is mathematically equivalent to a Public Key, but is kept secret. This is one half of a matching key-pair.
Public Key A Public Key is a publicly distributed key, used in Asymmetric Encryption. It is mathematically equivalent to a Private Key, but is widely distributed. This is the other half of a matching
key-pair.
PKCS#1 In cryptography, PKCS #1 is the first of a family of standards called Public-Key Cryptography Standards (PKCS), published by RSA Laboratories. It provides the basic definitions of and recommendations for implementing the RSA algorithm for public-key cryptography. It defines the mathematical properties of public and private keys, primitive operations for encryption and signatures, secure cryptographic schemes, and related ASN.1 syntax representations.
PKCS#8 In cryptography, PKCS #8 is a standard syntax for storing private key information. PKCS #8 is one of the family of standards called Public-Key Cryptography Standards (PKCS) created by RSA Laboratories. The latest version, 1.2, is available as RFC 5208.
Base64 Base64 is a group of similar binary-to-text encoding schemes that represent binary data in an ASCII string format by translating it into a radix-64 representation. The term Base64 originates from a specific MIME content transfer encoding. Each base64 digit represents exactly 6 bits of data. Three 8-bit bytes (i.e., a total of 24 bits) can therefore be represented by four 6-bit base64 digits.
DER DER (Distinguished Encoding Rules) is a restricted variant of BER for producing unequivocal transfer syntax for data structures described by ASN.1. Like CER, DER encodings are valid BER encodings. DER is the same thing as BER with all but one sender’s options removed. DER is a subset of BER providing for exactly one way to encode an ASN.1 value. DER is intended for situations when a unique encoding is needed, such as in cryptography, and ensures that a data structure that needs to be digitally signed produces a unique serialized representation. DER can be considered a canonical form of BER. For example, in BER a Boolean value of true can be encoded as any of 255 non-zero byte values, while in DER there is one way to encode a boolean value of true.
ASN.1 Abstract Syntax Notation One (ASN.1) is an interface description language for defining data structures that can be serialized and deserialized in a standard, cross-platform way. It is broadly used in telecommunications and computer networking, and especially in cryptography.
PEM PEM is a de facto file format for storing and sending cryptography keys, certificates, and other data, based on a set of 1993 IETF standards defining “privacy-enhanced mail.” While the original standards were never broadly adopted, and were supplanted by PGP and S/MIME, the textual encoding they defined became very popular. The PEM format was eventually formalized by the IETF in RFC 7468.

Many cryptography standards use ASN.1 to define their data structures, and Distinguished Encoding Rules (DER) to serialize those structures. Because DER produces binary output, it can be challenging to transmit the resulting files through systems, like electronic mail, that only support ASCII. The PEM format solves this problem by encoding the binary data using base64. PEM also defines a one-line header, consisting of “—–BEGIN “, a label, and “—–“, and a one-line footer, consisting of “—–END “, a label, and “—–“. The label determines the type of message encoded. Common labels include “CERTIFICATE”, “CERTIFICATE REQUEST”, and “PRIVATE KEY”.

PEM data is commonly stored in files with a “.pem” suffix, a “.cer” or “.crt” suffix (for certificates), or a “.key” suffix (for public or private keys).[2] The label inside a PEM file represents the type of the data more accurately than the file suffix, since many different types of data can be saved in a “.pem” file.

 

Example Private & Public Keys

What is a Key Pair? A Key Pair is a PKCS#1 encoded private key that also contains the public key. A lot of information on the Internet mentions that the public key can be recreated from the private key. This is not correct. The public key is extracted from the private key by copying two values which are stored in the private key file: The Modulus and Public Exponent. The Modulus and Public Exponent are then written as a PKCS#1 encoded file.

A big source of confusion is caused by the fact that there is another common format: PKCS#8. This encoding wraps the ASN.1 portion of a PKCS#1 encoded private or public key within another encoding. This additional encoding includes additional information that describes the data that follows (the PKCS#1 information). You can create PKCS#1 from PKCS#8 by throwing away the PKCS#8 header SEQUENCE objects (unwrapping).

How do you determine if a private key file is PKCS#1 or PKCS#8? Simple, look at the file contents.

A PKCS#1 file has the text string “—–BEGIN RSA PRIVATE KEY—–” at the beginning of the file and the text string “—–END RSA PRIVATE KEY—–” at the end of the file. This is called wrapping the key.

A PKCS#8 file starts with the text string “—–BEGIN PRIVATE KEY—–” and ends with the text string “—–END PRIVATE KEY—–“. Notice that the word RSA is missing from PKCS#8.

The same style is used for the public key: “—–BEGIN RSA PUBLIC KEY—–” versus “—–BEGIN PUBLIC KEY—–“.

Here is an example PKCS#1 private key file:

 

Here is an example PKCS#1 public key file:

 

The file contents between the wrapping (“—–BEGIN RSA PRIVATE KEY—–“) is a base64 encoding of the public or private key. A private key is an ASN.1 data structure, serialized to a byte string using DER, and base64 encoded. Sounds complicated and this is where some of the confusion arises. Note that the OpenSSH format does not use DER / ASN.1 encoding. Its format is much simpler (length preceded binary data).

A more accurate description: PEM DER ASN.1 PKCS#1 RSA Private Key

OpenSSH Public Keys

There is another public key file encoding and that is the OpenSSH encoding. This encoding format is used by SSH servers within the authorized_keys file. Let’s start with this format as this is the simplest to understand and take apart.

Here is an example OpenSSH public key file (notice that it starts with ssh-rsa).
The public key is the same as the PKCS#1 public key just encoded
differently.

SSH-2 Public Keys

Now to really add to the confusion, there is another SSH format called SSH-2. This format is used by AWS. Notice the similarity with PKCS#1 with the BEGIN SSH header. Also, notice that the public key part is the same as OpenSSH (the part that begins with AAAAB3).

Examining OpenSSH Public Keys

Let’s take apart the OpenSSH public key. We will start by unpacking the two fields, base64 decode the public key back to binary and take apart the binary to see the Modulus and Public Exponent. We will do this in Python. The source code to this example (example1.py) and the private/public keys displayed above and in the repository.

The first step is to create the public and private keys that we will be examining. I wrote a Windows batch script to create the keys and set read-only permissions on the private key file. If you do not set the correct read-only permissions on the private key file, ssh-keygen.exe will complain and abort. ssh-keygen.exe insists on only supporting protected private key files.

The repository contains make_keys.bat which includes enhanced versions that include error checking that I do not include below.

File make_keys.bat

Executing make_keys.bat will create four files and set the correct permissions on the private key file. The repository includes the batch file make_keys_8.bat which will create PKCS #8 files from the PKCS #1 files. We will look at PKCS #8 later.

  • test1.pem – This is the RSA private key – PKCS #1
  • test1.pub – This is the RSA public key – PKCS #1
  • test1.pem – This is the OpenSSH public key
  • test1.pem – This is the SSH-2 public key

OpenSSL has an option to parse ASN.1 data structures. Let’s look at a simple example first, the public key, and then a complex example, the private key.

Execute the following command:

The output will look like this:

The Modulus is the long (2048-bit) number that starts with C93A.
The Public Exponent is 010001 (decimal 65537) which is the default used by openssl when creating private keys.

Another way to view the Modulus is to use this openssl command:

Notice the same Modulus in the output.

Now let’s look at the private key test1.pem. Notice that you will find the same two numbers (Modulus and Public Exponent) in the private key data structures. Now you know for certain that the public key is stored in the PKCS #1 private key data structures.

Before looking at the ASN.1 decode of the private key, let’s review the ASN.1 syntax that defines the data is stored in a private key.

The ASN.1 syntax for the DER-encoded private key is described in RFC 3447 (aka PKCS #1):

 

Only the modulus, publicExponent and privateExponent are required for asymmetric encryption and decryption. The other numbers are helpful for improving the performance of the algorithms.

Let’s define each number:

Term Definition
modulus The result of multiplying p (prime1) and q (prime2). Called n. Its length, expressed in bits,
is the key length.
publicExponent The public exponent used for encryption and decryption. Called e. The public key consists of the modulus (n) and the public exponent (e).
privateExponent The private exponent used for encryption and decryption. Called d. The private key consists of the modulus (n) and the private exponent (d).
prime1 The first of two prime numbers that are multiplied together to produce the modulus. Called p.
prime2 The second of two prime numbers that are multiplied together to produce the modulus. Called q.
exponent1 A result stored to improve RSA performance. Refer to the
Chinese Remainder Theorem. Calculated from d mod (p – 1).
exponent2 A result stored to improve RSA performance. Refer to the
Chinese Remainder Theorem. Calculated from d mod (q – 1).
coefficient A result stored to improve RSA performance. Refer to the
Chinese Remainder Theorem. Calculated from (inverse of q) mod p.
otherPrimeInfos Additional information that can be included.

To see the ASN.1 output, execute the following command:

Refer to the ASN.1 syntax and the table above to understand each number. The order of each number is defined in the ASN.1 syntax.

Credits

I write free articles about technology. Recently, I learned about Pexels.com which provides free images. The image in this article is courtesy of Pixabay at Pexels.