CryptoSys Home > PKI > RSA Key Formats

RSA Key Formats


This document explains the various ways in which RSA keys can be stored, and how the CryptoSys PKI Toolkit handles them.

Creating a new key pair

The function RSA_MakeKeys (Rsa.MakeKeys Method) creates a new RSA key pair in two files, one for the public key and one for the private key. The private key is saved in encrypted form, protected by a password supplied by the user, so it is never saved explicitly to disk in the clear.

Creating a new RSA key pair

Creating a X.509 certificate

To create an X.509 certificate, you use the function X509_MakeCert (X509.MakeCert Method) like this:

Creating an X.509 certificate

There is special kind of certificate called a "self-signed" certificate, normally made by a Certification Authority (CA), but you can make your own using the key pair you created above and the function X509_MakeCertSelf (X509.MakeCertSelf Method).

Creating a self-signed X.509 certificate

You can use this certificate together with the private key to sign certificates for other subjects. You can also import this certificate into your own PC using the CERTMGR program as a "Trusted Root Certification Authority". Your system will then "trust" all certificates issued by the self-signed certificate. (CAUTION: never install an unknown certificate on your computer as trusted; you never know what mischief it may allow).

In practice, you use your own private key combined with your requested Distinguished Name details and the function X509_CertRequest (X509.CertRequest Method) to create a Certificate Signing Request (CSR) and then send it along with a fee to a Certification Authority (CA) like Verisign who will issue a properly-trusted certificate and return it to you. Note that your private key details are not sent to the CA: only your public key is included.

Creating a certificate signing request

Internal Representation

Most functions involving RSA keys in the CryptoSys PKI Toolkit require the public or private key to be provided as a string in an "internal" format. A few functions require the actual key file itself. This internal format is an encrypted form of the key in base64 encoding valid only for the current session, see Internal key strings in the manual. There are a variety of functions provided to extract the public and private keys from files of various formats and to save them back to alternative formats.

Key File Encoding

Key data may be encoded in three general ways:

Binary DER-encoded format
This is sometimes called ASN.1 BER-encoded (there is a subtle difference between BER- and DER-encodings: DER is just a stricter subset of BER, but consider them the same here). The most compact form. If you try to view the file with a text editor it is full of "funny" characters. The first byte in the file should be a '0' character (U+0030).
PEM or base64 format
This is the same data as the DER-encoded file but it is encoded in base64 with additional header and footer lines:
-----BEGIN FOO BAR KEY-----
MIIBgjAcBgoqhkiG9w0BDAEDMA4ECKZesfWLQOiDAgID6ASCAWBu7izm8N4V
2puRO/Mdt+Y8ceywxiC0cE57nrbmvaTSvBwTg9b/xyd8YC6QK7lrhC9Njgp/
...
-----END FOO BAR KEY-----

These files can be viewed with a text editor and can be easily transmitted as part of an email message. The first character in the base64-encoded part should be a 'M' (U+004D).

XML format
There are W3C standards for this, and, er, a .NET way that predates the latest W3C standard. Here is an example of the W3C [XKMS] 2.0 format
<RSAKeyPair>
  <Modulus>4IlzOY3Y9fXoh3Y5f06wBbtTg94Pt6vcfcd1KQ0FLm0S36aGJtTSb6pYKfyX7PqCUQ8wgL6xUJ5GRPEsu9
    gyz8ZobwfZsGCsvu40CWoT9fcFBZPfXro1Vtlh/xl/yYHm+Gzqh0Bw76xtLHSfLfpVOrmZdwKmSFKMTvNXOFd0V18=
  </Modulus>
  <Exponent>AQAB</Exponent>
  <P>9tbgIiFMXwpw/yf85bNQap3lD7WFlsZA+qgKtJubDFXCAR35N4KKFMjykw6SzaVmIbk80ga/tFUxydytypgt0Q==</P>
  <Q>6N6wESUJ0gJRAd6K6JhQ9Xd3YaRFk2sIVZZzXfTIWxKTInOLf9Nwf/Wkqrt0/Twiato4kSqGW2wU6K5MnvqOLw==</Q>
  <DP>l0zwh5sXf+4bgxsUtgtqkF+GJ1Hht6B/9eSI41m5+R6b0yl3OCJI1yKxJZi6PVlTt/oeILLIURYjdZNR56vN8Q==</DP>
  <DQ>LPAkW/qgzYUi6tBuT/pszSHTyOTxhERIZHPXKY9+RozsFd7kUbOU5yyZLVVleyTqo2IfPmxNZ0ERO+G+6YMCgw==</DQ>
  <InverseQ>
    WIjZoVA4hGqrA7y730v0nG+4tCol+/bkBS9u4oiJIW9LJZ7Qq1CTyr9AcewhJcV/+wLpIZa4M83ixpXub41fKA==
  </InverseQ>
  <D>pAPDJ0d2NDRspoa1eUkBSy6K0shissfXSAlqi5H3NvJ11ujNFZBgJzFHNWRNlc1nY860n1asLzduHO4Ovygt9DmQb
    zTYbghb1WVq2EHzE9ctOV7+M8v/KeQDCz0Foo+38Y6idjeweVfTLyvehwYifQRmXskbr4saw+yRRKt/IQ==
  </D>
</RSAKeyPair>
The white space in the content or between the tags should not matter, at least as far as our functions are concerned. The .NET version uses <RsaKeyValue> instead, which is strictly only for a public key.

How to read in an RSA Key

X.509 public key certificates are usually named .cer or .der. A textual PEM-format version might be named .pem or .crt. An X.509 certificate is essentially a signed copy of the user's public key plus various other identifying information including the subject's distinguished name (DN). Private keys stored using the PKCS#8 convention are conventionally named .p8 or .p8e, but you'll also find .pri, .key, .bin and .pem being used (we used to use .epk in our examples for encrypted private keys - but .p8e is preferred).

You can read in the public key from an X.509 certificate or a public key file using the RSA_ReadAnyPublicKey function (Rsa.ReadPublicKey Method in .NET).

You read in the private key from a BER or PEM private key file or directly from a PFX (.p12) file using the RSA_ReadAnyPrivateKey function (Rsa.ReadPrivateKey Method in .NET).

To read in from an XML file, in all cases, XML data needs to be read into a string and then read in using the RSA_FromXMLString function. See Importing an RSA key from known parameters.

Public key certificates can also come in Cryptographic Message Syntax Standard PKCS#7 format, P7Chain (typically named .p7b or .p7c, but sometimes mischeviously named .cer) or as part of a PKCS#12 PFX file (typically called .pfx or .p12). The PKCS#7 files might contain several certificates in a chain. Use the X509_GetCertFromP7Chain and X509_GetCertFromPFX functions to extract a single X.509 certificate from P7c and PFX files respectively. Encrypted private keys can also come in PFX format: use the RSA_GetPrivateKeyFromPFX function to extract a PKCS#8 encrypted private key file.

Public and private key formats supported

These "raw" public and private key formats are supported by the CryptoSys PKI Toolkit:

Public key formats supported

Encrypted private key formats supported

Private key formats supported (unencrypted)

* compatible with the examples in S/MIME Examples [SMIME-EX]
** compatible with OpenSLL

References

Contact

For more information or to comment on this page, please send us a message.

This page last updated 3 February 2021