This content has moved - please find it at https://devblog.cyotek.com.

Although these pages remain accessible, some content may not display correctly in future as the new blog evolves.

Visit https://devblog.cyotek.com.

Creating a code signing certificate with StartSSL

Edit 02Jan2017: Even if you wanted to ignore the revelations of dubious practices of StartSSL and with them now being owned by WoSign, there is another matter to consider - StartSSL authenticode certificates don't support lifetime signing. Meaning, when your certificate has expired, your signed binaries are no longer trusted, negating the point of signing them in the first place. For this reason, I don't recommend using StartSSL any further.

The process of obtaining a code signing certificate from StartSSL differs significantly from the process I originally went through with Comodo. This blog post serves to document how I did it for StartSSL, both as a reference for myself and for anyone else! Personally I find this approach easier than fiddling around exporting certificates from a browser, and it gives you a lot more control.

This post assumes you have already validated a level 2 personal/organization identity with StartSSL. Free level 1 validations cannot be used to create code signing certificates.

The usual caveat applies - I have tested this process and signed software with the final certificate and all seems well. However, it's entirely possible I'm missing something and something drastic given the apparent compromising of the previous certificate. I'll update this post should I discover anything untoward, but your mileage may vary. I am not a security expert.

Prerequisites

In order to generate the certificate signing request (CSR) and convert the certificate, you're going to need to use OpenSSL. As I'm running on Windows, you'll more than likely want to download pre-compiled Win32 binaries - you can find these here. I mostly use 64bit versions of Windows, but I found the 32bit version of OpenSSL to suffice.

The OPENSSL_CONF environment variable, or avoiding "WARNING: can't open config file: /usr/local/ssl/openssl.cnf"

When trying to use the OpenSSL command line tools, you may receive WARNING: can't open config file: /usr/local/ssl/openssl.cnf. It might be a warning, but it is a fatal one.

If this happens, just run the following line in your command window (or add it to your batch script), replacing the path as appropriate for your local installation.

SET OPENSSL_CONF=C:\OpenSSL-Win32\bin\openssl.cfg

As a side note, the OpenSSL installer does register this as a global environment variable, but it doesn't seem to kick in right away - I received this warning when initially testing on a Windows 8.1 development machine, and I received it again when installing on an XP VM for testing as I write this post.

A note on paths

By default, the OpenSSL installer linked to above will install the binaries to your Windows system directory. If (as I did) you choose not to do this, you will either need to include the OpenSSL bin folder in your path, include the path in the executable call, or set the current directory to the OpenSSL bin folder. Whatever method you choose, the rest of this article assumes that this has been done.

Generating the certificate signing request

A CSR or Certificate Signing request is a block of encrypted text that is generated on the server that the certificate will be used on. It contains information that will be included in your certificate such as your organization name, common name (domain name), locality, and country (source).

StartSSL requires a CSR that you need to create yourself. Although this might sound a little ominous (and something StartSSL could improve upon, as they offer zero guidance on the subject) it's pretty easy to do.

Open a command window and run the following command, replacing yournamehere as appropriate.

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

When you run the command, you'll be asked for a number of different values, such as Country, State, Common Name and so on. Make sure these values match the details you have validated with StartSSL.

Once you have submitted all the requested values, OpenSSL will generate both a certificate request and a private key with a bit size of 2048. By default it will use the SHA1 algorithm. For a more secure key, change 2048 to a larger value such as 4096. Do not use a value lower that 2048 however.

You've probably heard that Google is doing away with SHA1 SSL and while I don't think this applies to code signing certificates, you may wish to use something newer, for example appending to the above command line -sha256 will use SHA2. However, I didn't discover this option until after I'd created the certificate so I can't say if this works or not. I also remember Windows XP didn't support one of the .NET SHA algorithms so this too may factor into your choice.

Copy yournamehere.key somewhere secure. If you lose this file, you won't be able to generate any more certificates from that CSR. And you don't want anyone else getting their hands on the key either.

Make sure all details are correct before submitting the CSR to StartSSL. You won't be able to create a new certificate without revoking the previous one - and StartSSL will charge you for this.

Open up yournamehere.csr in your favourite text editor, copy out the entire contents of the file and paste it into StartSSL's CSR request field and submit the form.

Creating the certificate

Once StartSSL has processed your request, you'll be able to download the certificate. When you request your certificate from them you'll be presented with another unfriendly form containing a block of text. Copy this into a new file and save it somewhere with a .crt extension.

If you double click this file from Windows Explorer, then it should display the certificate allowing you to check all the details.

The certificate you have just downloaded is actually in PEM format, but Windows doesn't recognize the .pem extension in order to view it as described above.

However, you're not quite done. Microsoft's signtool.exe command requires that certificates be in the Personal Information Exchange (PFX) format instead. So we'll need to convert the certificate using the private key we created earlier.

Open a command window and run the following, as usual replacing file names as appropriate. If you omit the -password argument then OpenSSL will prompt for one. Older versions of Windows only support password lengths of 32 characters. Make sure the password is as secure as you can, random characters, symbols, the works.

If your chosen password includes the & character, surround the password in double quotes otherwise the command parser will get a little confused and the command will fail

openssl pkcs12 -export -out yournamehere.pfx -inkey yournamehere.key -in yournamehere.crt -password pass:"yourpasswordhere"

This should then generate yournamehere.pfx in a format that signtool.exe will understand. Don't lose the password, you'll need it whenever you use the certificate to sign files or to import the certificate into a store.

Unlike with the .crt file, trying to open the .pfx file will display a wizard for importing the certificate into your store.

And you're done

With these simple steps complete you now have a certificate that you can use to code sign your programs. Good luck!

Example signtool.exe usage

Although this article is about creating the certificate, it only make sense to quickly outline the right parameters for signing your files. Again, I'm assuming that signtool.exe is somewhere in your path for the below command line to work.

Edit 2016Jul27: According to Micheal Herrmann's comment, the time stamping URL is now http://tsa.startssl.com/rfc3161, so if the example below no longer works try this URL instad.

signtool sign /f yournamehere.pfx /p yourpasswordhere /tr http://www.startssl.com/timestamp yourfilehere.exe

If you've previously use another timestamping service, you may have used /t <url> - this won't work with StartSSL's timestamp server, you must use the /tr parameter instead.

Update History

  • 2014-12-31 - First published
  • 2016-07-27 - Added note about timestamping URLs
  • 2017-01-02 - Added warning about code signing certificates
  • 2020-11-21 - Updated formatting

About The Author

Gravatar

The founder of Cyotek, Richard enjoys creating new blog content for the site. Much more though, he likes to develop programs, and can often found writing reams of code. A long term gamer, he has aspirations in one day creating an epic video game. Until that time, he is mostly content with adding new bugs to WebCopy and the other Cyotek products.

Leave a Comment

While we appreciate comments from our users, please follow our posting guidelines. Have you tried the Cyotek Forums for support from Cyotek and the community?

Styling with Markdown is supported

Comments

Bertrand

# Reply

Thank for this really helpful information.

Michael Herrmann

# Reply

I've also found this incredibly helpful. Thank you very much.

Michael Herrmann

# Reply

When running the "signtool" command with the parameters you suggested, I received the following error:

SignTool Error: An unexpected internal error has occurred. Error information: "Error: SignerSign() failed." (-2145844843/0x80190195)

The reason for this is that StartSSL's timestamp URL has changed. It should be:

signtool sign /f yournamehere.pfx /p yourpasswordhere /tr http://tsa.startssl.com/rfc3161 yourfilehere.exe

Thanks again!

Gravatar

Richard Moss

# Reply

Michael,

Thanks for the comments, I'm glad you found the guide useful. Also thank you for pointing out the URL no longer works - I'll update the article accordingly.

While I still use StartSSL certificates, I don't use their timestamping server so I never noticed it had broke.

Regards;
Richard Moss

Otso

# Reply

Thanks to you for posting this very helpful info :)

Gravatar

Teus Benschop

# Reply

Thank you for the helpful information.

Gravatar

Fernando

# Reply

You can create custom CSR from windows without OpenSSL?

Regards

Gravatar

Richard Moss

# Reply

Hello,

Yes you can, in fact I mostly use online CSR generators when creating CSR's for SSL certificates for things like Azure services where I don't have direct access to the server. I still use OpenSSL for generating the CSR for code signing certificates though as it works for me and I also used OpenSSL to convert certificates between formats. But that doesn't mean it's the best and/or only way.

Regards; Richard Moss