PGP / GnuPG / OpenPGP Message Encryption in JavaScript© Herbert Hanewinkel |
23.Feb.2005
updated 17.Jan.2011Why encryption in Javascript?
For securing web forms with public key encryption.
Public key encryption in Javascript encrypts form data at the client side for the whole transfer from sender to the final receiver. Form data can be transferred without using an SSL connection and is stored encrypted on the server. Only the final receiver can decrypt it.
How to integrate it with existing PKI?
There are other pages about encryption in Javascript. All these pages demonstrate how encryption/decryption could be done in Javascript.
- They use Javascript forms for encryption and decryption.
- Many sites use small key sizes for demonstrating the public key encryption only.
- Because of the slow performance on decryption in Javascript, they propose server side decoders in other languages,
e.g. shop-js.sourceforge.net- a special mail reader with decryption software in Java
How to secure form data without any "special" processing software for decryption using standard keys sizes (>= 1024 bits)?
My provider offers a CGI program formmail.pl to forward form data as mail, a solution that is offered by most providers.
The idea:Encryption could be done automatically and hidden before transmission.
- Create an OpenPGP encrypted and ASCII armored message from form data in Javascript.
- The CGI program formmail.pl forwards the encrypted contents as mail.
- The mail is automatically decrypted by the receiver using a GnuPG/PGP mail plugin.
Decryption is done automatically by a GnuPG mail plugin for your favorite mail client.The OpenPGP message format is described in RFC 2440 / RFC 4880 and implemented in the GnuPG software. PGP message encryption is based on symmetric encryption of a message using a random session key and public key encryption of the session key.
Today's mail encryption standards recommend to use MIME for marking encrypted contents, but the "old" ASCII armored inline message format of PGP is well suited for encryption of form data in Javascript.
OpenPGP supports RSA as one of the public key encryption algorithms. John Hanna implemented a RSA/RC4 encryption scheme in Javascript for a client based Webshop. RC4 was choosen by John Hanna for symmetric encryption because RC4 is fast and small in code size. But RC4 is not supported by OpenPGP. For symmetric encryption of a message one of the OpenPGP supported algorithms was needed. I used Fritz Schneider's AES (Rijndael) reference implementation as a first choice, but the performance was very poor compared to RC4. Porting the optimized GnuPG C implementation of AES to Javascript improved the situation.
My solution: OpenPGP Message Encryption in Javascript
My contact form offers encryption for sending me confidental messages. It is coded to use my PGP 1024 bit RSA public key.
My PGP Encryption Service enables you to PGP/GPG encrypt a message for a receiver as a web based service. It is implemented in Javascript code only, executed in your local browser and readable for verification.
The Javascript Sources:
- rsa.js -- RSA encryption/decryption
(modified version of John Hanna's RSA implementation, the fastet RSA encryption in Javascript I could find).- aes-enc.js -- AES encryption.
- mouse.js -- entropy collection from mouse motion and key press timing.
- pgencode.js -- OpenPGP message encoding.
- base64.js -- OpenPGP radix-64 encoding.
Additional routines:
- pgpubkey.js -- RSA/Elgamal public key extraction from a PGP public key block.
- sha1.js -- SHA-1 implementation from Paul Johnston for OpenPGP Version 4 key ID calculation.
Decryption
Many people ask me about decryption in Javascript. I don't think that it could be really useful to do decryption in Javascript, because it requires the secret key and I would never paste my secret key in a web form.
The packet decoder could be used as a starting point and extended for decrypting PGP encrypted messages:
Secret keys are stored by GPG by default CAST-128 encrypted.
- pgdecode.js -- Extracts values from PGP key and data blocks.
- PGP packet decoding -- Simple frontend for pgdecode.js.
- cast5.js -- CAST-128 encryption/decryption.
How the algorithms work:
There are other pages about the mathematical background of public key encryption and AES. The two links below don't give a description of RSA, Elgamal or AES algorithm itself, but they show how the two encryption parts of the Javascript implementation work. My OpenPGP message encryption is based on these Javascript routines:
Is it secure?
- yes
- The software encrypts form data at the client before transmission using strong public key encryption. An encrypted message is secured at the level provided by an RSA or Elgamal 1024 bit key, e.g. decryption of a single message will need a few month.
- no
- Javascript code and public key of the receiver are transferred unencrypted from server to client and therefore could be modified on the fly by a third person. A person getting access to your server can modify Javascript code and public key of the receiver.
References & Links:
There are many links about encryption and Javascript. Links explaining and demonstrating RSA public key encryption using small numbers, ... Here a few links that I found useful for implementing my solution.
- RFC 4880: OpenPGP message format
- Gnu Privacy Guard
- John Hanna's Javascript Shopping & Crypto System
- Paj's Home: Cryptography: JavaScript SHA-1, MD5, ...
- John Walker's Browser-Based Cryptography Tools
- RFC 2144: The CAST-128 Encryption Algorithm
Support:
If you have questions regarding the software, send me a mail.
Please note that I can not answer requests about encryption in general.
www.haneWIN.net | Home |