Showing posts with label gnupg. Show all posts
Showing posts with label gnupg. Show all posts

Saturday, November 03, 2007

Google Analytics Google Gadget

With the NaNoWriMo gadget a success, I've been working on another gadget. This one displays your Google Analytics statistics.


So my blog doesn't really get that many hits, that's just the screenshot of the gadget in action that the Google Gadget Directory wanted.

Note how the gadget creates a new tab for each profile in your account. Also, that's what the previous couple posts about PGP and GnuPG/GPG encryption were all about--I'm encrypting the Analytics username/password.

I barely published it, so it won't show up in the Google Gadget directory for a few days, assuming Google doesn't have a problem with it.

Encrypting to PGP / GnuPG / GPG using Javascript

In a previous post I wrote about receiving PGP-encrypted data and using GnuPG (GPG) from a PHP script to decrypt it. In this post I'm going to show the client-side, a webpage (or in my case, a Google Gadget) that uses Javascript to PGP-encrypt sensitive information and send it to a server. Yes, you could use SSL, but the destination I was sending it to didn't have an SSL certificate.

To do the Javascript encryption, I modified some code from Herbert Hanewinkel, and I'll post the necessary Javascript include files, which he makes available.
<!--Create a holding variable that will be used later -->
<input type="hidden" name="keyid" id="keyid" value="">

<!-- Drop your public key into an invisible textarea. It's called public for a reason; there's no danger in letting people see it. -->

<textarea id="public_key" name="public_key" style="display:none;">
-----BEGIN PGP PUBLIC KEY BLOCK-----
Version: GnuPG v1.4.2 (GNU/Linux)

mQGiBEcrXY0RBACao9CBQL/BggPP5HcnWXLV/O5MEYhAAg3kl6l6Xu3CVKtGlw5d
P8CJSZuPZSrcQs+GI4PAkS1AH4f7Ex7phwUIMak6ufv5wX5iWU4JwxDCuvYOmlyz
l4iMsH5uJSI7QvQ7zl9QR3KC/qONZ5EWYiW7Gu/1yJ6JuykM2vumhi9CMwCg9KZy
vh5HDynAEf+8PbeD9z7aRcED/1x2muLD1gt5fSBSyyCjcvYtQ8od+UT/GwVpCMRu
Eq+t0uBrrecKmQ9GzkXhnP7KXLe7NDgTZwxAqTjMAkf+v/v5HOnBClOdzoS6EAFO
JotlB+SJiqXoClvhfHRJKhJwyMfKlmGUAWr9itaWQbdLXo5BGqDyaoXjw5jyQ4ch
yf5PA/wMjqDcUux8eOGivU63CGLHriHRMT2QtPSU73zDf3X8+X9EPZxLPZ7SCFTO
YCeyNBe5PvMsk0n8ZO/Gnezxh345NtJ9LXxk+65svGaxnTPQksdzOJAzE8KjlHDF
ZNGl52J6R/TPOxwBSt42ackTfn50IJJC/0kSvHRKck+Ll4MR4bQ7QmVuamFtaW4g
SGFyZGluIChHb29nbGUgQW5hbHl0aWNzKSA8ZXZpbG92ZXJsb3JkQGdtYWlsLmNv
bT6IYAQTEQIAIAUCRytdjQIbAwYLCQgHAwIEFQIIAwQWAgMBAh4BAheAAAoJEJ3f
PyIusymjPNcAnAqILzNRYnpk2xD0ruE0OJyGZ4OoAJoDSV9G/rVmNVVjTb2PMwMm
v49UgbkBDQRHK12NEAQAsZW2iev4FbLAaYZJ073DP1F+RuzNaa+KplQ4pHnoci2l
7JqTD+iVlODdpWbzEYQursq5L2v7xdKRN56aga0AV4j0JCXouc5atYsGCY6OY7PT
OGWMB21y8K8I9LM/9h/YZblc+7pChqeC9dJ1pL8G9dhNh02cMyEwp8BuTsx39IMA
AwUD/3+Ei+zt/rWFFtHMMByvqyRnqk8U3QWiTgN8DhY+9lol7w2OCgKjFaVZUqzt
pQnAXO665er49suqrx8riZ6Lan0YO6swxjQ8C7BUj9/fMDAlDBfpOspWDMzYu/9e
fOAqk3z8PJlPIUlMxIwy6a1wuoSt2ko3wmP2VH6Mv+0dltrriEkEGBECAAkFAkcr
XY0CGwwACgkQnd8/Ii6zKaNB5ACg33r2gxWkiZidQLZRXg5sidz7KAoAn3ajmkuL
vO273vANfSgRe9MrGJAI
=aiWr
-----END PGP PUBLIC KEY BLOCK-----

</textarea>

<!-- Include some required files. They are hyperlinked! Download them now! -->
<script language="Javascript" src="rsa.js" type="text/javascript"> </script>
<script language="Javascript" src="aes-enc.js" type="text/javascript"> </script>
<script language="Javascript" src="sha1.js" type="text/javascript"> </script>
<script language="Javascript" src="base64.js" type="text/javascript"> </script>
<script language="Javascript" src="mouse.js" type="text/javascript"> </script>
<script language="Javascript" src="PGencode.js" type="text/javascript"> </script>
<script language="Javascript" src="PGpubkey.js" type="text/javascript"> </script>

<script language="Javascript">

var keytyp = -1;
var keyid = '';
var pubkey = '';

function getkey()
{
    var pu = new getPublicKey( document.getElementById( "public_key" ).value );
    if(pu.vers == -1) return;

    document.getElementById("keyid").value = pu.keyid;

    /* I didn't end up needing this variable in the encrypt function, since I already knew the key type was Elgamal */
    /* document.getElementById( "pktype" ).value = pu.type; */

    pubkey = pu.pkey.replace(/\n/g,'');
}

/* Pass in the data to encrypt */
function encrypt(text)
{
    keyid='0000000000000000';
    if( document.getElementById( "keyid" ).value.length )
        keyid=document.getElementById( "keyid" ).value;

    if(keyid.length != 16)
    {
        alert('Invalid Key Id');
        return;
    }

    /* Since I already knew my key type was Elgamal, I didn't need this block of code. I just set "keytype=1" below. */
    /*
    keytyp = -1;
    if( document.getElementById( "pktype" ).value == 'ELGAMAL')
        keytyp = 1;
    else if( document.getElementById( "pktype" ).value == 'RSA')
        keytyp = 0;

    if(keytyp == -1)
    {
        alert('Unsupported Key Type');
        return;
    }
    */
    keytyp = 1;

    return doEncrypt(keyid, keytyp, pubkey, text);
}

var encrypted_data = encrypt("sensitive data here!");
alert(encrypted_data);

/*
Special Note: I was forced to send the data through a URL (i.e. a GET rather than a POST). This forced me to encode the data prior to attaching to URL. Contains "+", so we must use "encodeURIComponent()" instead of "escape()". (See below for how the server-side PHP script will handle the received data.) */
encrypted_data = encodeURIComponent(encrypted_data);

/* Do something with the data. */
window.location = "http://www.test.com/index.php?encrypted_data="+encrypted_data;
</script>

Here's what happens on the server side, in the PHP script that receives it. (In the previous blog post about the PHP side I just pulled the encrypted data from a file, but here's what I was really doing.)
<?php
/* Reverse the effects of the Javascript "encodeURIComponent" */
$encrypted_data = rawurldecode( $_GET['encrypted_data'] );

/* From here, jump right into the PHP script outlined in the previous post, commenting out the line where you're pulling the encrypted data from a file, since you just got it from the GET request. */
?>

Friday, November 02, 2007

Setting up GnuPG (GPG) for use with PHP

Step 1 (failed):
$ pecl install gnupg

downloading gnupg-1.3.1.tar ...
Starting to download gnupg-1.3.1.tar (-1 bytes)
.............done: 124,416 bytes
5 source files, building
running: phpize
Configuring for:
PHP Api Version: 20020918
Zend Module Api No: 20020429
Zend Extension Api No: 20050606
`phpize' failed

Step 2 (success). Some information drawn from http://www.php.net/manual/en/install.pecl.php, a basic tutorial on how to install PECL extensions.
$ cd /usr/lib64/php/extensions

(This is where my PHP extensions [files with .so extension] are stored)
$ pecl download gnupg
$ tar -zxvf gnupg-1.3.1.tgz
$ cd gnupg-1.3.1/
$ phpize
$ ./configure
$ make
$ make install

"gnupg.so" now appears in /usr/lib64/php/extensions
Now I need to install the extension in the php.ini file
$ whereis php.ini

/etc/php.ini
$ vi /etc/php.ini

Find the list of extensions in php.ini, in my case headed by "[extension section]". Add "extension=gnupg.so" to the end of the list, save and exit.
Now I need to restart apache so the extension takes effect.
$ apache2ctl graceful

Now do some PHP coding. Assumes you have GnuPG (gpg) installed, and have set up your key pair ("gpg --gen-key"). Some of these steps might be unnecessary, but after hours of fiddling around, I'm not about to walk through it again and find the essential ones.
/* Change this to your own path */
putenv("GNUPGHOME=/home/bch36/.gnupg/");

$encrypted_data = file_get_contents("encrypted.gpg");

$res = gnupg_init();

gnupg_seterrormode($res,GNUPG_ERROR_WARNING);

/* Change this to your own fingerprint. Find your fingerprint by running "gpg --fingerprint" from the commandline. Comment this out when everything works. */
print_r(gnupg_keyinfo($res,"ASDF1234QWER5678ZXCV9012ASDF3456QWER7890"));

/* Put your own fingerprint and passphrase here. Also, this function will fail unless you see Important Note #1 below */
gnupg_adddecryptkey($res, "ASDF1234QWER5678ZXCV9012ASDF3456QWER7890", "put your secret passphrase here");

/* You'll want to comment this out when everything is working */
echo gnupg_geterror($res);

/* This function will fail unless you see Important Note #2 below */
$plain = gnupg_decrypt($res, $encrypted_data);

Important Notes:
1. To get gnupg_keyinfo() to work, you'll need to let your webserver have some access to your keyring. Do the following (replace "www" with the group that your own webserver runs under):
> cd /home/bch36/.gnupg
> chown :www pubring.gpg trustdb.gpg
> chmod 660 pubring.gpg trustdb.gpg

2. To get gnupg_decrypt() to work, you'll need to grant more access. Note that the webserver will now have access to your secret key! However, if you don't do the following, the gnupg_decrypt() function will fail and you'll get the following warning when printing out gnupg_geterror(): "Warning: gnupg_adddecryptkey() [function.gnupg-adddecryptkey]: get_key failed in ..."
> chown :www secring.gpg
> chmod 660 secring.gpg

As a possible point of interest, I'm only doing decryption because I want a remote webpage to use Javascript to PGP encrypt data and send it to my PHP file, which can then decrypt it. I guess it's a workaround for not having SSL. I'll try to post an entry about the client-side next (Javascript PGP).