PHP Openssl Sending Encrypted Email To Outlook

Posted on 2006-05-22
Last Modified: 2008-01-09
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.
Question by:globalgr
    LVL 21

    Expert Comment

    by:Julian Matz
    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.

    Author Comment

    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.
    LVL 21

    Expert Comment

    by:Julian Matz
    Ok, I actually think there's also an extension for Outlook... Hang on and I'll have a look...
    LVL 21

    Expert Comment

    by:Julian Matz

    Found it... The Outlook plugin:

    Here's the official GnuPG site:

    Author Comment

    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.
    LVL 11

    Expert Comment


    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.

    Author Comment

    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?
    LVL 21

    Expert Comment

    by:Julian Matz
    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...
    LVL 21

    Expert Comment

    by:Julian Matz

    $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); ?>

    Author Comment

    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?
    LVL 21

    Expert Comment

    by:Julian Matz
    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>";

    Author Comment

    It did return with a directory listing.
    LVL 21

    Expert Comment

    by:Julian Matz
    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...

    Author Comment

    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).
    LVL 21

    Expert Comment

    by:Julian Matz
    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...
    LVL 21

    Accepted Solution

    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...

    Author Comment

    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.

    Author Comment

    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.

    Write Comment

    Please enter a first name

    Please enter a last name

    We will never share this with anyone.

    Featured Post

    Looking for New Ways to Advertise?

    Engage with tech pros in our community with native advertising, as a Vendor Expert, and more.

    As this topic comes over and over again in different forms, I've finally decided to write a short (yea, right...) article / tutorial about pagination with PHP with MySQL database. There are dozens of these kind of tutorials, I know - I wanted to mak…
    This is a general how to create your own custom plugin system for your PHP application that you designed (or wish to extend a third party program to have plugin functionality that doesn't have it yet).  This is not how to make plugins for existing s…
    Explain concepts important to validation of email addresses with regular expressions. Applies to most languages/tools that uses regular expressions. Consider email address RFCs: Look at HTML5 form input element (with type=email) regex pattern: T…
    The viewer will learn how to count occurrences of each item in an array.

    779 members asked questions and received personalized solutions in the past 7 days.

    Join the community of 500,000 technology professionals and ask your questions.

    Join & Ask a Question

    Need Help in Real-Time?

    Connect with top rated Experts

    10 Experts available now in Live!

    Get 1:1 Help Now