A private web application needs to receive encrypted email from perhaps 20 known users. How can I use OpenSSL to generate a valid encryption certificate that Outlook users can import and use to encrypt emails which can be decrypted after being received by an email address connected to my app?

Towards this end, I started using the code from @logicalscope's answer to this other posting, which I will summarize here as follows:

$ openssl genrsa -aes128 -out email.key 2048
$ openssl req -new -key email.key -out email.csr -config email.cnf
$ openssl x509 -req -days 365 -in email.csr -CA ca.crt -CAkey ca.key -set_serial 10 -out email.crt
$ openssl pkcs12 -export -in email.crt -inkey email.key -out email.pfx  

Where email.cnf is created in advance of the preceding steps as:

[ req ]
default_bits           = 2048
distinguished_name     = req_distinguished_name
prompt                 = no

[ req_distinguished_name ]
C                      = {Country}
ST                     = {Provice/State}
L                      = {City}
O                      = {Org}
OU                     = {Org Unit}
CN                     = user@domain.com
emailAddress           = user@domain.com  

The problem is that the code above does not know where to look for ca.crt. Therefore, the line openssl x509 -req -days 365 -in email.csr -CA ca.crt -CAkey ca.key -set_serial 10 -out email.crt results in the following:

Signature ok
Error opening CA Certificate ca.crt
140570916620192:error:02001002:system library:fopen:No such file or directory:bss_file.c:398:fopen('ca.crt','r')
140570916620192:error:20074002:BIO routines:FILE_CTRL:system lib:bss_file.c:400:
unable to load certificate

How can I generate a valid ca.crt in a way that will enable Outlook users to use email.pfx to encrypt emails that my app can decrypt upon receipt? Do I need to purchase a certificate? This is just for a development server at the moment. It would be nice to get something to work that is free. For example, Thunderbird users are able to send emails encrypted with a GPG key that my app is able to decrypt.

My devbox is running Windows 7 and Outlook 2010.

migrated from security.stackexchange.com Feb 25 '15 at 12:38

This question came from our site for information security professionals.


The script below creates a certificate authority (CA) and an email cert. The email cert is signed by the CA created. I used the template for email.cnf that you provided above. Note that I upgraded the cryptography to 4096 bit RSA keys, SHA256, and AES256. Also all places where you need to change items are surrounded by < >. It will ask you for local passwords when running the script.

Serial_number_CA=<Serial number you want to use>
Serial_number_leaf=<Serial number you want to use>
Passphrase=<password you want to use>

echo openssl genrsa -aes256 -out $Certauth_key $RSA_size
openssl genrsa -aes256 -out $Certauth_key $RSA_size

echo openssl req -new -x509 -set_serial $Serial_number_CA -days $Lifespan_in_days -config $Config_file -key $Certauth_key -out $Certauth_crt
openssl req -new -x509 -set_serial $Serial_number_CA -days $Lifespan_in_days -config $Config_file -key $Certauth_key -out $Certauth_crt

echo openssl genrsa -aes256 -out $Key_name $RSA_size
openssl genrsa -aes256 -out $Key_name $RSA_size 

echo openssl req -new -key $Key_name -out $CSR_name -config $Config_file 
openssl req -new -key $Key_name -out $CSR_name -config $Config_file 

echo openssl x509 -req -sha256 -days $Lifespan_in_days -in $CSR_name -CA $Certauth_crt -CAkey $Certauth_key -set_serial $Serial_number_leaf -out $CRT_name -setalias $Frendily_name -clrtrust -addtrust emailProtection -addreject clientAuth -addreject serverAuth -trustout
openssl x509 -req -sha256 -days $Lifespan_in_days -in $CSR_name -CA $Certauth_crt -CAkey $Certauth_key -set_serial $Serial_number_leaf -out $CRT_name -setalias $Frendily_name -clrtrust -addtrust emailProtection -addreject clientAuth -addreject serverAuth -trustout

echo openssl pkcs12 -export -aes256 -in $CRT_name -inkey $Key_name -out $Email_PFX_name -name $Frendily_name -passout $PasswordPhrase
openssl pkcs12 -export -aes256 -in $CRT_name -inkey $Key_name -out $Email_PFX_name -name $Frendily_name -passout $PasswordPhrase 

In Thunderbid, you need to first import the CA into your trusted authorities and then import the email cert under your certificates for signing. This is also true when attempting to send an encrypted reply to a signed email if that cert does not chain to a trusted CA. Therefore if the other party is using Thunderbird, you will need to send them your ca.crt. If you are encrypting email to another party, you will need their .crt (any any .cer's in the chain) before being allowed to send them a message. This was not needed when replying to a signed mail under Outlook if you explicitly trust the cert.

I'm still getting a strange error if I place the key both in the Digital Signing and the Encryption box in Thunderbird. Despite this, I can send signed and encrypted mail with another account, just not both at once. Also, when loading the CA in Thunderbird, it tells me that the CA can be used for SSL signing. At some point in the future, I need to figure out why the label says so.

This code was used on OpenSSL 1.0.2d 9 Jul 2015 under Cygwin 2.2.1(0.289/5/3) running under Windows 10 build 1057. I tested this with a gmail account using Thunderbird (38.8.0) sending encrypted and signed messages to a Microsoft hosted exchange service using Outlook

  • Thank you and +1 for taking the time to look into this old question. I cannot verify the answer right now. But I have bookmarked this question so that I can refer to your answer when i am ready to revisit this. – CodeMed Oct 4 '15 at 12:38

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.