Skip to content

Instantly share code, notes, and snippets.

@wzxjohn
Forked from crazybyte/certs.txt
Created May 13, 2017 13:50
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save wzxjohn/8a5bb6af8816178ad379601b57507286 to your computer and use it in GitHub Desktop.
Save wzxjohn/8a5bb6af8816178ad379601b57507286 to your computer and use it in GitHub Desktop.
OpenSSL transformations
NOTE: HTTP SSL keys are all in PEM format (base64 encoded)
#From PEM format to DER
openssl x509 -in $1.crt -out $1.der -outform DER
#From DER format to PEM
openssl x509 -in $1.der -inform DER -out $1.pem -outform PEM
#Transforming RSA key to DER format
openssl rsa -in oberon.key -inform PEM -out oberon_key.der -outform DER
=============================================================================================================
Procedure
1. Ensure that the certificate(s) and key are in PEM format:
To convert a certificate from DER to PEM:
openssl x509 –in input.crt –inform DER –out output.crt –outform PEM
To convert a key from DER to PEM:
openssl rsa –in input.key –inform DER –out output.key –outform PEM
To convert a key from NET to PEM:
openssl rsa –in input.key –inform NET –out output.key –outform PEM
Note: The obsolete NET (Netscape server) format is encrypted using an unsalted RC4 symmetric cipher so a passphrase will be requested. If you do not have access to this passphrase it is unlikely you will be able to recover the key.
Use the openssl command to read the PEM encoded certificate(s) and key and export to a single PKCS#12 file as follows:
openssl pkcs12 -export -in input.crt -inkey input.key -out bundle.p12
Note: By default the key will be encrypted with Triple DES so you will be prompted for an export password (which may be blank).
Note: The PEM formatted root certificate and any other certificates in the chain can be concatenated into a single file (for example, root.crt) and included in the PKCS#12 file as follows:
openssl pkcs12 -export -in input.crt -inkey input.key -certfile root.crt -out bundle.p12
NOTE: The resulted custom certificate bundle can be imported into browsers to avoid the security notifications related to self-signed or custom certificates.
=============================================================================================================
Use the openssl command to convert between formats as follows:
To convert a certificate from PEM to DER:
x509 -in input.crt -inform PEM –out output.crt -outform DER
To convert a certificate from DER to PEM:
x509 -in input.crt -inform DER -out output.crt -outform PEM
To convert a key from PEM to DER:
rsa -in input.key -inform PEM -out output.key -outform DER
To convert a key from DER to PEM:
rsa -in input.key -inform DER -out output.key -outform PEM
=============================================================================================================
This post finishes my epic about the implementation of RSA encryption. See the part I and part II of my post about RSA encryption for C++/Delphi (CryptoAPI) and PHP (OpenSSL) applications.
The main problem we faced was incompatibility of key formats. CryptoAPI uses PRIVATEKEYBLOB and PUBLICKEYBLOB formats to export and import RSA keys while OpenSSL extension for PHP uses PEM format. In order to use both libraries in communicating applications we needed some tool to convert keys from one format to another. The only tool we found for this was OpenSSL 1.0.x beta. Notice that earlier versions of OpenSSL do not support CryptoAPI BLOBs.
Update: It was found later that CryptoAPI has native functions for key conversion. See “Update” section at the bottom of the post.
Below is a command line syntax example for conversion of private key from PEM to PRIVATEKEYBLOB format:
openssl rsa -inform PEM -in private.pem -outform MS\ PRIVATEKEYBLOB -out private.blob
And this example converts PUBLICKEYBLOB to PEM format:
openssl rsa -pubin -inform MS\ PUBLICKEYBLOB -in public.blob -outform PEM -out public.pem
Notice that backslash (\) in format names. You need to type it as it actually escapes the space character.
However, we found some drawbacks in usage of OpenSSL 1.0.x beta:
There was no Windows build of it available at the time of the post but we wanted to convert keys on Windows.
We also wanted to convert keys directly in our code w/o any need for external application.
As far as PRIVATEKEYBLOB, PUBLICKEYBLOB and PEM format structures are known, we decided to develop code that will read and write them using low-level functions. It actually took 1-2 days for me to develop that code so I don’t think it’s a really hard task.
Later we faced another problem: PHP versions prior to 5.2 don’t support openssl_pkey_get_details function. Once again, handling key formats directly helped us to resolve the issue by providing a replacement for the function.
So, let me explain how you can implement reading/writing PEM, DER, PRIVATEKEYBLOB and PUBLICKEYBLOB formats with some code examples in PHP for PEM and DER formats and in C++/VCL for CryptoAPI BLOBs. As the task was a part of a commercial project I cannot post a complete working example here. But I will do my best helping you to assemble such code on your own. You can also request our service at Pumka.net.
Understanding RSA Key Formats
The first thing you need to know is that any key format is actually a container for the set of long numbers. All other data could be considered “noise”.
Private key contains: modulus, private exponent, public exponent, prime 1, prime 2, exponent 1, exponent 2 and coefficient.
Public key contains only modulus and public exponent.
Once you can read these numbers from one format and put them to another, you can covert keys. You can also export public keys for private ones this way.
PEM format produced by OpenSSL is actually base64 encoded and wrapped key data in the binary format called DER. Thus, to work with PEM format you must actually work with DER.
DER format is based on Abstract Syntax Notation One (ASN.1) standard. The standard specifies encoding of tree-like data structures. Two predefined data structures are used for private and public RSA keys. Though I didn’t find a good parser for the format, with a couple of notes from the standard in hand I wrote a class for encoding and decoding ASN.1 values.
PRIVATEKEYBLOB and PUBLICKEYBLOB formats are actually C-style PRIVATEKEYBLOB and PUBLICKEYBLOB structures. You can use pointer manipulation and memory copy to parse them. Notice that these formats use little-endian byte order for integer values unlike DER format which uses big-endian order. Thus, you’ll need to reverse integer byte sequences when converting key data from BLOB to DER or vise versa.
Source: http://pumka.net/2009/12/19/reading-writing-and-converting-rsa-keys-in-pem-der-publickeyblob-and-privatekeyblob-formats/
=============================================================================================================
Certificates: File Format & Conversion
The user must also be aware that OpenSSL supports several certificate formats. Certificates are based on the DSA signature algorithm and the RSA algorithm for public-key cryptography according to PKCS algorithms, as described in [7].
The certificate format depends on the application, as there is no agreement on file format standards.
Private keys are usually available in the PEM and DER format. The related files have names of the following type:
*key-rsa.pem for pem files
*key-rsa.der for der files
For OpenSSL applications, the PEM format should suffice. For Java applications, the DER format might be more suitable for importing the private key and certificates.
For certificates, the available formats are PEM, DER and PKCS12 with file names of the following type:
*cert.pem for pem files
*cert.der for der files
*cert.p12 for pkcs12 files
In general, the PEM formats are mostly used in the Unix world, PCKS12 in the Microsoft world and DER in the Java world.
Certificate files are ASN.1-encoded objects that may be encrypted according to DES (Data Encryption Standard). The files can optionally be encrypted using a symmetric cipher algorithm, such as 3DES.
An unencrypted PEM file might look something like this:
-----BEGIN CERTIFICATE-----
MB4CGQDUoLoCULb9LsYm5+/WN992xxbiLQlEuIsCAQM=
-----END CERTIFICATE-----
The string beginning with MB4C... is the Base64-encoded, ASN.1-encoded object.
An encrypted file would have headers describing the type of encryption used, and the initialization vector:
-----BEGIN RSA PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED
DEK-Info: DES-EDE3-CBC,C814158661DC1449
AFAZFbnQNrGjZJ/ZemdVSoZa3HWujxZuvBHzHNoesxeyqqidFvnydA==
-----END RSA PRIVATE KEY-----
The two headers Proc-Type and DEK-Info declare the type of encryption, and the string starting with AFAZ... is the Base64-encoded, encrypted, ASN.1-encoded object.
As web browsers make use of Java applications, they import/export certificates in pkcs12 file format, i.e. public and private keys are packed in one single file using the PKCS#12 algorithm. Other applications require the pem format with unpacked public and private keys, thus the user must remember the appropriate file format for each application and must perform format conversions as appropriate.
The following tables report a summary of formats used for INFN-Grid applications and two simple scripts with format conversion commands.
INFN-Grid Certificates Format Summary
Certificate Type Certificate Format
CA Authority Certificate DER
Personal Certificate from CA PKCS12
Grid Access Certificate PEM
CONVERT pkcs12 to pem
#!/bin/sh
#
echo "copy your cert to cert.p12 - then run this script"
#
openssl pkcs12 -clcerts -nokeys -in cert.p12 -out usercert.pem
openssl pkcs12 -nocerts -in cert.p12 -out userkey.pem
CONVERT pem to pkcs12
#!/bin/sh
#
echo "Verify that you are using the correct certificate pair (key/cert)"
#
openssl pkcs12 -export -out cert.p12 -inkey ./userkey.pem -in ./usercert.pem
Source: http://www.bo.infn.it/alice/introgrd/certmgr/node2.html
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment