Thursday, June 5, 2014

OpenSSL vs. the Microsoft crypto stack

I'd like to publish a Microsoft Word VBA macro for my co-workers. I would also like to have it digitally signed, so that Word doesn't complain about scary insecure macros.

I know that my organization runs a certificate authority (CA) on a Microsoft platform. Every corporate computer trusts that CA. The CA has a Web-based UI for requesting certificates, but doesn't explicitly allow for requesting code signing certificates. It has, however, an "Advanced certificate request" form, where you can paste a Base64-encoded certificate signing request. The problem is creating one that the Microsoft crypto stack (including VBA) would play nicely with.

There are numerous tutorials on the Web regarding code signing certificate generation, but those mostly deal with either commercial certificate vendors, or with self-signed certificates. This case is somewhere in between.

By now, I've found a way to generate an arbitrtary CSR using Microsoft tools. But back at the time, I've decided to go all low-level with OpenSSL under Cygwin. OpenSSL has all the necessary commands for creating RSA keys, certificate signing requests (CSRs), and signed certificates.

First, you need to create a private/public RSA key pair:

openssl genrsa -out Key.pem 2048

This generates an unencrypted, 2048-bit RSA key pair and stores it in Key.pem.

Now you need to put together a CSR with your information. Some of the parameters can't be set from the command line, so a config file is in order. It would looks like this:


CN=John Doe
OU=Software Engineering
O=Acme Software
L=New York


The contents of the DN ("distinguished name") section will go into the "Subject" line in the final certificate. The 1.OU line has to do with the fact that the config file syntax doesn't allow for several OU lines ("organizational units") in a section, but the certificate/CSR syntax does. Also, the DN should be written in reverse order; in the final certificate, the order of fields will be from bottom to top.

Save this as req.txt, and run the following command:

openssl req -new -config req.txt -key Key.pem -out SignReq.pem

SignReq.pem now contains the CSR in Base64 form. Paste its contents into the CA's Web form (or use whatever submission mechanism your CA uses), and wait for approval from whoever runs the CA.

Once the approval comes, you'll receive a signed certificate file. Depending on the CA, you may get it either in PEM format (text, Base64-encoded), or in DER (binary). In the latter case, you can use OpenSSL to convert (assuming SignedCert.der is the binary file you've got from the CA):

openssl x509 -in SignedCert.der -inform DER -out SignedCert.pem -outform PEM

Microsoft tools assign the .cer extension to certificates in both PEM and DER format. You can view either by double-clicking in Windows Explorer. But the following OpenSSL command requires the certificate as PEM.

Now you need to convert the private key and the signed certificate to PFX form, so that Windows may import it into the certificate store. For that, use the following command:

openssl pkcs12 -export -in SignedCert.pem -inkey Key.pem -out CertWithKey.pfx

It will prompt for an export password; memorize it, as you'll need it to import the certificate/key pair into Windows' store. It will generate a file called CertWithKey.pfx that would contain both the signed certificate and the private key.

Now double-click the CertWithKey.pfx file in Windows Explorer (or right-click and choose "Install PFX"). The import UI will pop up; click through it, and provide the export password from the step above when prompted. On the same screen, I'd recommend marking the key as exportable and enabling private key protection.

That's it. Now the certificate should appear whenever you're choosing one in VBA.

All the OpenSSL commands I've mentioned are documented here.

No comments:

Post a Comment