Public key cryptography (asymmetric cryptography) is the foundation of the Internet and it is used for a variety of purposes.
Public and private keys can be stored in several different types of files. Each of these types can have its own encoding. The overall format of a file can be quite complex. It is important, however, to understand the purpose of these formats, and how they’re used.
This document can be used as a primer for understanding these file/encoding formats.
The actual structure (objects and fields) of public/private keys, including X.509 certificates, is specified in various RFCs using the ASN.1 notation.
For example, an RSA private key contains the following fields:
RSAPrivateKey ::= SEQUENCE {
version Version,
modulus INTEGER, -- n
publicExponent INTEGER, -- e
privateExponent INTEGER, -- d
prime1 INTEGER, -- p
prime2 INTEGER, -- q
exponent1 INTEGER, -- d mod (p-1)
exponent2 INTEGER, -- d mod (q-1)
coefficient INTEGER, -- (inverse of q) mod p
otherPrimeInfos OtherPrimeInfos OPTIONAL
}
The most widely used format is X.509 and it’s full syntax is defined by the RFC5280. X.509 provides the support for the “chain of trust” to verify a public key, as well as various extensions, primarily concerning the key’s usage. RFC5280 also documents formats for CSR, CLR, etc.
PKCS #8 specification defines the structure of private keys (PKCS stands for Public-Key Cryptography Standards).
These specifications only stipulate the structure (fields and objects), we still need to decide how to “encode” these fields when we want to save them on disk.
Security considerations aside, it would be nice if everything was stored in some sort of a structured format that we’re all used to, such as JSON or YAML, but this not the case for the majority of crypto formats, with the exception of JWK as explained later.
Read the rest of this post »