OpenPGP.js [![Build Status](https://travis-ci.org/openpgpjs/openpgpjs.svg?branch=master)](https://travis-ci.org/openpgpjs/openpgpjs) [![Test Coverage](https://codeclimate.com/github/openpgpjs/openpgpjs/badges/coverage.svg)](https://codeclimate.com/github/openpgpjs/openpgpjs/coverage) [![Code Climate](https://codeclimate.com/github/openpgpjs/openpgpjs/badges/gpa.svg)](https://codeclimate.com/github/openpgpjs/openpgpjs) ========== [OpenPGP.js](http://openpgpjs.org/) is a Javascript implementation of the OpenPGP protocol. This is defined in [RFC 4880](http://tools.ietf.org/html/rfc4880). [![Saucelabs Test Status](https://saucelabs.com/browser-matrix/openpgpjs.svg)](https://saucelabs.com/u/openpgpjs) ### Platform support * OpenPGP.js supports node.js v0.12+ and browsers that implement [window.crypto.getRandomValues](http://caniuse.com/#feat=getrandomvalues). * The api uses ES6 promises which are available in [most modern browsers](http://caniuse.com/#feat=promises). If you need to support browsers that do not support Promises, fear not! There is a [polyfill](https://github.com/jakearchibald/es6-promise), which is included in our build. So no action required on your part! * For the OpenPGP HTTP Key Server (HKP) client the new [fetch api](http://caniuse.com/#feat=fetch) is used. There is a polyfill for both [browsers](https://github.com/github/fetch) and [node.js](https://github.com/bitinn/node-fetch) runtimes. These are not bundled in the library however and you must add these yourself. See the unit tests for examples of how to integrate them. ### Performance * Version 2.x of the library has been built from the ground up with Uint8Arrays. This allows for much better performance and memory usage than strings. * If the user's browser supports [native WebCrypto](http://caniuse.com/#feat=cryptography) via the `window.crypto.subtle` api, this will be used. Under node.js the native [crypto module](https://nodejs.org/api/crypto.html#crypto_crypto) is used. This can be deactivated by setting `openpgp.config.useNative = false`. * For environments that don't provide native crypto, the library falls back to [asm.js](http://caniuse.com/#feat=asmjs) implementations of AES-CFB, SHA-1, and SHA-256. We use [Rusha](https://github.com/srijs/rusha) and [asmCrypto Lite](https://www.npmjs.com/package/asmcrypto-lite) (a minimal subset of asmCrypto.js built specifically for OpenPGP.js). ### Getting started #### Npm npm install --save openpgp #### Bower bower install --save openpgp Or just fetch a minified build under [dist](https://github.com/openpgpjs/openpgpjs/tree/master/dist). ### Examples Here are some examples of how to use the v2.x api. If you're upgrading from v1.x it might help to check out the [documentation](https://github.com/openpgpjs/openpgpjs#documentation). #### Set up ```js import openpgp from 'openpgp.js'; // use as ES6, CommonJS, AMD module or via window.openpgp openpgp.initWorker({ path:'openpgp.worker.js' }) // the relative Web Worker path ``` #### Encrypt and decrypt *String* data with a password ```js let options, encrypted; options = { data: 'Hello, World!', // input as String passwords: ['secret stuff'] // multiple passwords possible }; openpgp.encrypt(options).then(armored => { encrypted = armored; // '-----BEGIN PGP MESSAGE ... END PGP MESSAGE-----' }); ``` ```js options = { message: openpgp.message.readArmored(encrypted), // parse armored message password: 'secret stuff' // decrypt with password }; openpgp.decrypt(options).then(plaintext => { // return 'Hello, World!' }); ``` #### Encrypt and decrypt *Uint8Array* data with PGP keys ```js let options, encrypted; const pubkey = '-----BEGIN PGP PUBLIC KEY BLOCK ... END PGP PUBLIC KEY BLOCK-----'; const privkey = '-----BEGIN PGP PRIVATE KEY BLOCK ... END PGP PRIVATE KEY BLOCK-----'; options = { data: new Uint8Array([0x01, 0x01, 0x01]), // input as Uint8Array publicKeys: openpgp.key.readArmored(pubkey).keys, // for encryption privateKeys: openpgp.key.readArmored(privkey).keys, // for signing (optional) armor: false // don't ASCII armor }; openpgp.encrypt(options).then(message => { encrypted = message.packets.write(); // get raw encrypted packets as Uint8Array }); ``` ```js options = { message: openpgp.message.read(encrypted), // parse encrypted bytes publicKeys: openpgp.key.readArmored(pubkey).keys, // for verification (optional) privateKey: openpgp.key.readArmored(privkey).keys[0], // for decryption format: 'binary' // output as Uint8Array }; openpgp.decrypt(options).then(plaintext => { // return Uint8Array([0x01, 0x01, 0x01]) }); ``` #### Generate new key pair ```js let options = { userIds: [{ name:'Jon Smith', email:'jon@example.com' }], // multiple user IDs numBits: 4096, // RSA key size passphrase: 'super long and hard to guess secret' // protects the private key }; openpgp.generateKey(options).then(key => { let privkey = key.privateKeyArmored; let pubkey = key.publicKeyArmored; }); ``` #### Lookup public key on HKP server ```js let hkp = new openpgp.HKP('https://pgp.mit.edu'); let options = { query: 'alice@example.com' }; hkp.lookup(options).then(key => { let pubkey = openpgp.key.readArmored(key); }); ``` #### Upload public key to HKP server ```js let hkp = new openpgp.HKP('https://pgp.mit.edu'); const pubkey = '-----BEGIN PGP PUBLIC KEY BLOCK ... END PGP PUBLIC KEY BLOCK-----'; hkp.upload(pubkey).then(() => { ... }); ``` ### Documentation A jsdoc build of our code comments is available at [doc/index.html](http://openpgpjs.org/openpgpjs/doc/index.html). Public calls should generally be made through the OpenPGP object [doc/openpgp.html](http://openpgpjs.org/openpgpjs/doc/module-openpgp.html). ### Security Audit To date the OpenPGP.js code base has undergone two complete security audits from [Cure53](https://cure53.de). The first audit's report has been published [here](https://github.com/openpgpjs/openpgpjs/wiki/Cure53-security-audit). ### Security recommendations It should be noted that js crypto apps deployed via regular web hosting (a.k.a. [**host-based security**](https://www.schneier.com/blog/archives/2012/08/cryptocat.html)) provide users with less security than installable apps with auditable static versions. Installable apps can be deployed as a [Firefox](https://developer.mozilla.org/en-US/Marketplace/Options/Packaged_apps) or [Chrome](https://developer.chrome.com/apps/about_apps.html) packaged app. These apps are basically signed zip files and their runtimes typically enforce a strict [Content Security Policy (CSP)](http://www.html5rocks.com/en/tutorials/security/content-security-policy/) to protect users against [XSS](https://en.wikipedia.org/wiki/Cross-site_scripting). This [blogpost](https://tankredhase.com/2014/04/13/heartbleed-and-javascript-crypto/) explains the trust model of the web quite well. It is also recommended to set a strong passphrase that protects the user's private key on disk. ### Development To create your own build of the library, just run the following command after cloning the git repo. This will download all dependencies, run the tests and create a minifed bundle under `dist/openpgp.min.js` to use in your project: npm install && npm test ### Mailing List You can [sign up](http://list.openpgpjs.org/) for our mailing list and ask for help there. We've recently worked on getting our [archive up and running](http://www.mail-archive.com/list@openpgpjs.org/). ### How do I get involved? You want to help, great! Go ahead and fork our repo, make your changes and send us a pull request. ### License GNU Lesser General Public License (3.0 or any later version). Please take a look at the [LICENSE](LICENSE) file for more information. ### Resources Below is a collection of resources, many of these were projects that were in someway a precursor to the current OpenPGP.js project. If you'd like to add your link here, please do so in a pull request or email to the list. * [http://www.hanewin.net/encrypt/](http://www.hanewin.net/encrypt/) * [https://github.com/seancolyer/gmail-crypt](https://github.com/seancolyer/gmail-crypt) * [https://github.com/mete0r/jspg](https://github.com/mete0r/jspg) * [http://fitblip.pub/JSPGP-Stuffs/](http://fitblip.pub/JSPGP-Stuffs/) * [http://qooxdoo.org/contrib/project/crypto](http://qooxdoo.org/contrib/project/crypto) * [https://github.com/GPGTools/Mobile/wiki/Introduction](https://github.com/GPGTools/Mobile/wiki/Introduction) * [http://gpg4browsers.recurity.com/](http://gpg4browsers.recurity.com/) * [https://github.com/gmontalvoriv/mailock](https://github.com/gmontalvoriv/mailock)