Showing posts with label decrypt. Show all posts
Showing posts with label decrypt. Show all posts

Saturday, November 03, 2007

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. */
?>