PHP Openssl Sending Encrypted Email To Outlook

I am trying to utilise php/openssl to encrypt information (with a high level of security) to be sent by email. I found the script below and have successfully encrypted the information and emailed it to myself.

/////SCRIPT - START/////
$data = '<<<EOD
MIME-Version: 1.0
Content-type: text/html; charset=iso-8859-1
<b>Nighthawk</b>,<h1>Top secret, for your eyes only!</h1><p>The enemy is closing in! Meet me at the cafe at 8.30am
to collect your forged passport!</p><p>HQ</p></html>EOD';

$key = implode("", file("PathToDir/certificate.pem"));
//the above *.pem file contains
//MIICxjCCAi+gAwIBHGFghGrfkA....etc etc
$clearfile = "PathToDir/random_file_name";
$encfile = $clearfile . ".enc";
$clearfile = $clearfile . ".txt";
$fp = fopen($clearfile, "w");
fwrite($fp, $data);
$pubkey = file_get_contents("PathToDir/certificate.pem");

$properties = array(
                  "To" => "",
                  "From" => "HQ <>",
                  "Subject" => "Encrypted Email"
openssl_pkcs7_encrypt($clearfile,$encfile, $pubkey, $properties, 0);                  
$data = file_get_contents($encfile);
$parts = explode("\n\n", $data, 2);

mail($mail, $subject, $parts[1], $parts[0]);
/////SCRIPT - END/////

My problems lies in how do I read the encrypted email on a windows machine in outlook. What do I need to import and where?

Also, I am not sure that I generated my certificates correctly (done using a different script that I found). The info I have is:

Proc-Type: 4,ENCRYPTED
DEK-Info: DES-EDE3-CBC,8B3754176550935C

CG9YW6OZazfdxvrs74JBsXDn....etc etc

MIICxjCCAi+gAwIBHGFghGrfkA....etc etc

MIIB6DCCAVECAQAwgacxCzAJB....etc etc

Also, for future reference can you please tell me the correct (& simple & straight forward) way to generate the certificate information using PHP and openssl. The PHP is installed on a linux (Red Hat) machine which is the remote webserver so I do not have direct access to the machine.

I have tried exec('openssl genrsa -des3 -out mykey.pem 1024'); and similar commands but get only an empty *.pem file.

Sorry for all the confusing questions but I am yet to find a straight forward answer to achieving this. Any help would be much appreciated.
Who is Participating?
Julian MatzConnect With a Mentor Joint ChairpersonCommented:
Actually, I just thought that it would be easier (and more secure) if you generate the keypair on your pc.

You can download GnuPG for Windows here:

When the keypair is generated, upload the public key to your server and use php to import it to the keyring:

<?php shell_exec("gpg --import /path/to/the/uploaded/key.txt"); ?>

Hope this works...
Julian MatzJoint ChairpersonCommented:
Hi globalgr,

I don't know how important it is for you to use openssl and outlook, but I've found that the best method for encrypting e-mail messages is by using GPG (the free GNU version of the military-strength PGP encryption), together with Mozilla Thunderbird as e-mail client.

GPG is extremely easy to use with PHP

There is an extension for Thunderbird called Enigmail which works absolutely perfectly.
globalgrAuthor Commented:
my computer is connected to an exchange server with all my accounts setup in outlook already. So switching my email client probably not an option, more of a last resort.

I don't care whether openssl or GPG is used as long as it works.
Free Tool: ZipGrep

ZipGrep is a utility that can list and search zip (.war, .ear, .jar, etc) archives for text patterns, without the need to extract the archive's contents.

One of a set of tools we're offering as a way to say thank you for being a part of the community.

Julian MatzJoint ChairpersonCommented:
Ok, I actually think there's also an extension for Outlook... Hang on and I'll have a look...
Julian MatzJoint ChairpersonCommented:

Found it... The Outlook plugin:

Here's the official GnuPG site:
globalgrAuthor Commented:
I am in the process of testing a GnuPG class script that I found; but, how can I tell if GnuPG is installed or not? I have had a look at the phpinfo page but there is no reference to it there.

This is a remote webserver that I have no control over, so if it is not installed I won't able to.

If it's not referenced in the output of phpinfo, it's probably not installed.

At the least, it should appear as a directory on the path section of phpinfo,   If the owner of the server has installed it in some directory that is not specifically named something like GnuPG, or gpg or similar, then it might be installed but is not easy to find.

Ask the server owner if it is installed.
globalgrAuthor Commented:
ok, after emailing server admin I have been told it is in fact installed (I was also given the path etc). As a starting point I will begin with the simple script below from Zend Technologies site.

$gpg = '/usr/bin/gpg';
$recipient = '';
$secret_file = '/home/PathToTextFile/FileName.txt';
echo shell_exec("$gpg -e -r $recipient $secret_file");

which echos nothing.

I know I need to do something relating to keyrings and adding my name to the keyring or something. Can you shed some light on how I do that from php?
Julian MatzJoint ChairpersonCommented:
Likely you will not be able to use the shell_exec() function. It is very insecure, so it will probably be disabled in php.ini.

I have developed a program which uses GPG and PHP. I'll just dig up some code snippets and post them...
Julian MatzJoint ChairpersonCommented:

$keyring = "/pubkeys/.gnupg"; // path to public keyring (this can be changed to a path within your home dir)
$fingerprint = '0ECC6954B683E5049236........'; // (this is to identify the public key)

$gpg = new gnupg();

putenv("GNUPGHOME=$keyring"); // set keyring to use

$gpg -> addencryptkey($fingerprint); // use the specified public key
$enc = $gpg -> encrypt("This is a test...."); // String to encrypt

echo $enc; // echo the encrypted string

The keyring path needs to be correct and you need to double-check the permissions for that directory and files. I spent hours trying to figure out why it wasn't working before I discovered that the permissions had been reverted back after using the gpg command in the shell CLI.

This is the way I started: I used Thunderbird with the Enigmail extension, and created a key pair (one public key for encryption and a private key for decryption) using the extension and my e-mail address. I then copied the public key to a text file and imported it to my keyring on the server. Then I got the fingerprint by using the gpg --fingerprint command and inserted the fingerprint to my php files. I think that was basically it...

You may not have shell access ??? which would make it a little more difficult. You would have to figure out a way to create the public keyring and import the pubkey to it using php. I didn't need to do this, so I haven't looked into this yet...

...Found a solution for importing the pubkey:

 $gpg = new gnupg();

 $keyring = "/pubkeys/.gnupg";
 putenv("GNUPGHOME=$keyring"); // to change the default GnuPG keyring home directory (--homedir)

 $keyblock = "[keyblock]";

 $result = $gpg -> import($keyblock);


(Replace [keyblock] with your actual keyblock). The keyring may already be set up in your home directory. You could try:
$keyring = "~/.gnupg";

You may also want to turn on error reporting to see if there are any errors:
<? error_reporting(E_ALL); ?>
globalgrAuthor Commented:
didn't even get past the first lines of your script

Fatal error: Cannot instantiate non-existent class: gnupg

Is there an include file I am missing with the class script?
Julian MatzJoint ChairpersonCommented:
Ok, this could be a problem then... Basically, my code depends on the gnupg extension being loaded. I installed PECL package ( .

Maybe you could try shell_exec() again, but chances are pretty high that it's disabled, either disabled in php.ini or disabled with safe_mode On. To test it you could try the following:

error_reporting(E_ALL); // will give you error reports
$output = shell_exec('ls -l'); // list directory contents
echo "<pre>$output</pre>";
globalgrAuthor Commented:
It did return with a directory listing.
Julian MatzJoint ChairpersonCommented:
Ok, in that case, it must work then :)

So, what you need to do first is generate your keypair. And you should probably know a little about the gpg commands... It's been a while since I did this, but try the following:

$output = shell_exec('gpg --help'); // list the gpg commands
echo "<pre>$output</pre>";

Here is the full online manual:

Using the shell_exec() function you should be able to execute all these shell commands.

You can either generate the keypair on your server - shell_exec('gpg --gen-key'); and then import your private key (which should then be deleted from the server), or you can generate the keypair on your local computer and export the public key to your server.

If you get stuck anywhere along the line, just come back to us and we'll try and help out...
globalgrAuthor Commented:
thanks for your help so far, hopefully one last question before I can dive in.
ok, I have never used shell_exec before so just a question about it's syntax.

If I want to execute: <?php  shell_exec("gpg --gen-key"); ?> How do I input the answers to the questions. According to I need to input the:
key type,
expiration date,

How do I input responses to these questions when normally at the command line I would be prompted (hope that makes sense).
Julian MatzJoint ChairpersonCommented:
Yes, that makes perfect sense, and to be honest I'm not sure... But I will try and get some info... May take me a while...
globalgrAuthor Commented:
thanks julian for your help. Although I am far from solving this problem I have outlined below the steps I haved used so far for any one else who may need them.


1) For the purpose of creating public key, install GNUPG for windows on local machine. (gnupg-w32cli-1.4.3.exe)

2) Create public key on local computer steps outlined below can also be found here
 - run exe and install
 - Go to Control Panel &#8594; System Properties &#8594; the Advanced tab &#8594; Environment Variables &#8594; System variables and add "c:\Program Files\GNU\GnuPG"
 - open command prompt and run
    - gpg --gen-key
    - gpg --armor --output "key.txt" --export "YOUR-NAME"

3) Find the created file and upload to webserver.

4) Run the following php commands to import key
   $ShellCommand = 'ls -la; ';   // use to check you can exec shell_exec commands
   $ShellCommand .= ' gpg --help;';  // use to verify existence of gpg on server
   $ShellCommand .= ' gpg --import public_key.txt; ';  // import newly created/uploaded key
   $ShellCommand .= ' gpg --list-keys;';   //list all keys
   $output = shell_exec("$ShellCommand");
   echo "<pre>$output</pre><br><br>";

5) Encrypt data using
 - $output = shell_exec('gpg --recipient "YOUR-NAME" --output "diary 2003-02.txt.gpg"  --encrypt "diary 2003-02.txt"');
or something similar.

6) Decrypting in outlook:
Install one of these outlook/gnupg plugins (more here: under plugins)

My problem is I get stuck on step 4, the key does not seem to import (or least there is no ouput) and --list-keys returns nothing, but for now I will have to leave it unless anyone can throw me a life line and tell why it doesn't work. I have tried printing errors to screen and just about every other solution/work around I can think of.
globalgrAuthor Commented:
I have since figured out how to do it using OpenSSL and MS Outlook.


Download and install from Shinning Light Productions OpenSSL binary for windows.
There are two versions available. If first one doesn't work try the other as one didn't work for me (don't remember which one).
This will be used for creating our certificates and keys locally before uploading.

After install run c:\Program Files\bin\openssl.exe to bring up the command line window.

Create a folder in a convenient location (mine was c:\mycerts)

In the openssl command line window enter the following commands. Some of these commands were taken from I have not gone into any detail on each of these commands, just follow on screen instructions after each command and enter required information.

COMMAND # 1) openssl genrsa -des3 -out c:\mycerts\ca.key
COMMAND # 2) openssl req -key c:\mycerts\ca.key -nodes -new -out c:\mycerts\ca.req
COMMAND # 3) openssl x509 -days 5000 -in c:\mycerts\ca.req -req -signkey c:\mycerts\ca.key -out c:\mycerts\ca.pem

make a copy and relocate and rename the files:
FROM c:\mycerts\ca.pem TO c:\Program Files\OpenSSL\bin\pem\demoCA\private\cacert.pem
FROM c:\mycerts\ca.key TO c:\Program Files\OpenSSL\bin\pem\demoCA\private\cakey.pem

COMMAND # 4) openssl ca -cert .\pem\demoCA\private\cacert.pem -ss_cert .\pem\demoCA\private\cacert.pem -out

Now using a text editor combine the files:
c:\Program Files\OpenSSL\bin\pem\demoCA\private\cacert.pem AND c:\Program Files\OpenSSL\bin\pem\demoCA\private\cakey.pem INTO A NEW FILE
c:\Program Files\OpenSSL\bin\pem\demoCA\private\cacert_plus_cakey.pem

COMMAND # 5) openssl pkcs12 -export -in .\pem\demoCA\private\cacert_plus_cakey.pem -out c:\mycerts\file_name.p12 -name "Name of Certificate"

You will now have a file with extension *.p12 in your folder. Import this file into internet explorer (outlook uses the same certificates as ie) Tools>Internet Options>Content>Certificates>Import
Select your p12 file and import.

Upload the file c:\Program Files\OpenSSL\bin\pem\demoCA\private\cacert.pem to somewhere on your remote webserver.

Now create your php code, very important you read this page for more sample code regarding exec(sendmail) vs mail


$data = <<<EOD

Top secret, for your eyes only!

The enemy is closing in! Meet me at the cafe at 8.30am
to collect your forged passport!


$key = implode("", file("/home/UserName/PathToCertificate/cacert.pem"));

$fp = fopen("msg.txt", "w");
fwrite($fp, $data);

$ArrayMessageProperties = array("To" => "", // keyed syntax
                           "From: HQ <>", // indexed syntax
                           "Subject" => "Eyes only");

if (openssl_pkcs7_encrypt("msg.txt", "enc.txt", $key, $ArrayMessageProperties))
   exec(ini_get("sendmail_path") . " < enc.txt");


 * Obviously go through and change all file names and paths that are relative to you.
 * Beware when entering passphrases write these down (and destroy later) as there are two (maybe three?) different passphrases/export password/challenge password (you'll figure it out).
 * I don't think it is necessary to run Command # 4 (not sure)
 * Check persmissions etc when creating encrypted data file.
 * As mentioned above consider using mail() rather that exec(sendmail).

This is very rough guide I know; but, hopefully this will help somebody figure it out a bit quicker than what it took me.
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.