Tag Archives: openssl - Page 2

Find A Matching Certificate And Key Pair

If you have a list of keys and SSL certs and don’t know which cert belongs with which key, here’s a script for you. It’s not efficient (nested for loop!), but it gets the job done quickly.1

#!/bin/bash
for i in `ls *.key` 
do
key_mod=`openssl rsa -noout -in $i -modulus`
for j in `ls *.cer`
do
x509_mod=`openssl x509 -noout -in $j -modulus`
if [ "$x509_mod" == "$key_mod" ]; then
echo "$j matches $i"
fi 
done
done
  1. If bash allowed multidimensional or associative arrays this would be trivial to optimize.

Create A 2048-bit Key Via OpenSSL

We are fast approaching the date where NIST has recommended that end entities stop utilizing 1024-bit private keys. OpenSSL, however, currently defaults to creating 1024-bit keypairs. To create a 2048-bit private key and corresponding CSR (which you can send to a certificate authority to obtain your SSL certificate):

openssl req -new -nodes -newkey rsa:2048 -keyout mydomain.key -out mydomain.csr

This command will make a 2048-bit key, run the interactive prompt to populate the fields of the certificate signing request, and leave the private key unencrypted (-nodes). You can remove -nodes if you wish, but encrypting the private key will require you to type the password every time you start an application (like apache) that uses it.

Check If A Certificate & Private Key Match

Check if an SSL certificate and private key match in two simple commands. The OpenSSL commands below will require you to replace <file> with your file’s name.

For your SSL certificate:1

openssl x509 -noout -modulus -in <file> | md5sum

For your RSA private key:

openssl rsa -noout -modulus -in <file> | md5sum

The output of these commands should be identical. If it isn’t, your keys do not match.

  1. The pipe to md5sum is solely to make the output shorter and easier to visually compare

Using OpenSSL s_time

Recently I needed to do some performance testing of an SSL instance on a VM. I considered using JMeter, but decided to use OpenSSL to get a rudimentary picture instead.

To obtain a basic result, we connect to the server and pull the /index.php file. You can specify whatever file you’d like to download, or none at all if you simply want to test connections.1

openssl s_time -www /index.php -new -connect www.trustwave.com:443

Your result will look something like this:

No CIPHER specified
Collecting connection statistics for 30 seconds
ttttttttttttttttttttttttttttttttttttttttttttttttttttttttt
159 connections in 5.82s; 27.32 connections/user sec, bytes read 62328
159 connections in 31 real seconds, 392 bytes read per connection

If you’d like to get more specific with performance testing you can even use the -ciphers parameter to explicitly choose the negotiated cipher. You can obtain a list of available ciphers with “openssl ciphers”.

  1. If you would prefer to reuse connections rather than create a new one for each request replace -new with -reuse.

RSA Encryption and Signing

OpenSSL provides several tools that allow you to RSA encrypt/sign arbitrary data files. Of course, directly RSA encrypting large volumes of data is impractical because the encrypted/signed data cannot exceed the size of the key material. This is one of the reasons why SSL connections typically handshake and then pass an AES (or RC4, et cetera) key to do symmetric encryption thereafter.1

Generate a private key. You can change the last number to the preferred modulus size. Keys greater than 4096-bit will take a long time to generate.2

openssl genrsa -out private.pem 4096

With the private key we can now encrypt the data.

openssl rsautl -encrypt -inkey private.pem -in publicfile -out privatefile

To decrypt just reverse it.

openssl rsautl -decrypt -inkey private.pem -in privatefile -out publicfile

If you would rather sign the data…

openssl rsautl -sign -inkey private.pem -in filetosign -out signed_data

To verify the signature just use -verify.3

openssl rsautl -verify -inkey private.pem -in signed_data
  1. Another big reason is speed. AES is much, much faster than RSA.
  2. If you attempt to encrypt or sign data larger than your key length allows, you will receive an error similar to this: 23465:error:0406D06E:rsa routines:RSA_padding_add_PKCS1_type_2:data too large for key size:rsa_pk1.c:151:
  3. You can also use -hexdump or -raw to view the data in those forms.

Creating a PKCS7 (P7B) Using OpenSSL

Continuing the howto nature of this blog (and its peculiar obsession with OpenSSL), here’s a primer on packaging an arbitrary number of certificates into a single PKCS7 container. These files are quite useful for installing multiple certificates on Windows servers. They differ from PKCS12 (PFX) files in that they can’t store private keys. If you need to generate a PKCS12 then head to that article instead.

This example assumes that you have 2 different certificate files, each in PEM (Base64) format. You can add as many -certfile elements as you want to package in the file. Additionally, concatenated certificate chains are supported. 1

openssl crl2pkcs7 -nocrl -certfile cert1.cer -certfile cert2.cer -out outfile.p7b
  1. If you wish to provide DER encoded input files (or have DER output) you can use the -inform DER or -outform DER directives.