Click here to Skip to main content
Licence CPOL
First Posted 2 Nov 2005
Views 32,095
Downloads 268
Bookmarked 9 times

Tiny OpenPGP - A small PHP implementation of GnuPG-style encryption

By | 28 Nov 2008 | Article
Tiny OpenPGP is encryption code that uses GnuPG principles but cuts out much of the fluff and flexibility for a straightforward implementation

Tiny OpenPGP v0.2b 


Introduction

Tiny OpenPGP is actually not compatible with the commercial software or its open source equivalent at all, but uses the fundamentals of asymmetric encryption to create encrypted+signed messages using AES and RSA. The title was chosen in-house and stuck. All of the things those packages do to enable multiple message types and encryption methods have been stripped out and is really only similar in concept.

This program uses mcrypt for Rijndael 256 (AES 256 bit) in order to do the symmetric portion of things and Crypt_RSA for the RSA portion. Crypt_RSA is a neat package that can use gmp, big_int, or bcmath to perform RSA functions, available from  http://pear.php.net/package/Crypt_RSA. Note that I had to correct the require_once('') paths, which were wrong, and I went ahead and flattened their multiple directory structure- but the code is otherwise unmodified.

How it works

The basic concept of asymmetric encryption is that you generate a random number to use as a symmetric key to encrypt the body. You then encrypt the random symmetric key using each desired recipient's public key and place it in a header at the top of the message. Next, encode the message using the random symmetric key (binary safe). Finally, sign the message using your private key.

The receiving code validates the signature of the entire message with the sender's public key then tries to fetch the session key back out of the header by attempting to use its private key on each of the encrypted session keys (one for each recipient) until the random key is found. Once found, the message body is decrypted.

Ordinarily, the private keys are encrypted symmetrically for storage and can only be retrieved by the person with the password used. I suggest this practice as well, just use aesEncrypt and aesDecrypt. The functions expect the unencrypted keys.

Bugs

I'm sure there are many, but the code works fine with a properly formatted message =)

I'll have to work on 'idiot proofing' later.

 

How To 

  1. Generate a Crypt_RSA public/private key pair of the desired length. (>=512bytes recommended, 1024 or better is preferred but slow with bcmath) 

                $key_pair = new Crypt_RSA_KeyPair($key_length);
                $public_key = $key_pair->getPublicKey();
                $private_key = $key_pair->getPrivateKey();

  2. (optionally) Encrypt the private key with aesEncrypt, using compression at your option (make sure to use the same setting for decryption)

                $encryptedKey = aesEncryptV2($private_key, $password, $compress);

                $password should probably be generated with binarySHA256($stringpassword)
               
       

  3. Save your key pair somewhere safe- you'll need it as long as you want to be able to decrypt messages encrypted using this pair
       
       
  4. When you're ready to send a message:
            a) create an array of the public keys of the people you want to send the message to
                $pubKeys[0] = ...;
                $pubKeys[1] = ...;
           
            b) if you encrypted your private key, decrypt it first
                $private_key = aesDecryptV2($encryptedKey, $password, $compressed);
           
            c) Now create your message. It will automatically be signed with your key.
                $encryptedMessage = create_message($messageBody, $pubKeys, $private_key);

       
  5. To receive a message:
            a)    If you encrypted your private key, decrypt it first
                    $private_key = aesDecryptV2($encryptedKey, $password, $compressed);

            b)    simply decrypt it with:
                    $result = decrypt_message($encryptedMessage, $public_key, $private_key);
           
            c)    check for ($result === false) - note the triple equals, otherwise $result contains your message

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

Brett Trotter

Systems Engineer
BT Technical Services
United States United States

Member



Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board. (secure sign-in)
 
Search this forum  
 FAQ
    Noise  Layout  Per page   
  Refresh
NewsTrademark Infringement PinmemberBrett Trotter8:07 28 Nov '08  
Just FYI: I received a message today:
 
Thanks very much for your submission to the Code Project. Your article http://www.codeproject.com/KB/HTML/Tiny_PGP.aspx has come to the attention of the PGP Corporation. As they have an established registered trademark they have requested that we slightly alter the use of their name within your article to include the registered trademark beside it, as well as alter the title of and description of your article slightly.
 

 
In the interest of cooperation and keeping your article we have made these minor changes to the article. Please let me know if you have any questions about this.

 

As such, you'll notice changes to the article. When I wrote the software, it wasn't for release and tiny pgp seemed as good a name as any, but when I wrote the article it did seem sort of silly to say it's not PGP compatible. I'm going to make some more changes to the article to remove references of PGP so that it doesn't say PGP (R) everywhere and reference asymmetric encryption instead.
NewsUpdated code PinmemberBrett Trotter16:24 21 Oct '08  
NewsUPDATES/CORRECTIONS [modified] PinmemberBrett Trotter4:42 3 May '07  
NewsRe: UPDATES/CORRECTIONS PinmemberBrett Trotter8:20 23 Sep '08  
QuestionRe: UPDATES/CORRECTIONS PinmemberEinarMagnus21:11 14 Oct '08  

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Permalink | Advertise | Privacy | Mobile
Web04 | 2.5.120604.1 | Last Updated 28 Nov 2008
Article Copyright 2005 by Brett Trotter
Everything else Copyright © CodeProject, 1999-2012
Terms of Use
Layout: fixed | fluid