README.md
1 # node-jwa [](https://travis-ci.org/brianloveswords/node-jwa) 2 3 A 4 [JSON Web Algorithms](http://tools.ietf.org/id/draft-ietf-jose-json-web-algorithms-08.html) 5 implementation focusing (exclusively, at this point) on the algorithms necessary for 6 [JSON Web Signatures](http://self-issued.info/docs/draft-ietf-jose-json-web-signature.html). 7 8 This library supports all of the required, recommended and optional cryptographic algorithms for JWS: 9 10 alg Parameter Value | Digital Signature or MAC Algorithm 11 ----------------|---------------------------- 12 HS256 | HMAC using SHA-256 hash algorithm 13 HS384 | HMAC using SHA-384 hash algorithm 14 HS512 | HMAC using SHA-512 hash algorithm 15 RS256 | RSASSA using SHA-256 hash algorithm 16 RS384 | RSASSA using SHA-384 hash algorithm 17 RS512 | RSASSA using SHA-512 hash algorithm 18 PS256 | RSASSA-PSS using SHA-256 hash algorithm 19 PS384 | RSASSA-PSS using SHA-384 hash algorithm 20 PS512 | RSASSA-PSS using SHA-512 hash algorithm 21 ES256 | ECDSA using P-256 curve and SHA-256 hash algorithm 22 ES384 | ECDSA using P-384 curve and SHA-384 hash algorithm 23 ES512 | ECDSA using P-521 curve and SHA-512 hash algorithm 24 none | No digital signature or MAC value included 25 26 Please note that PS* only works on Node 6.12+ (excluding 7.x). 27 28 # Requirements 29 30 In order to run the tests, a recent version of OpenSSL is 31 required. **The version that comes with OS X (OpenSSL 0.9.8r 8 Feb 32 2011) is not recent enough**, as it does not fully support ECDSA 33 keys. You'll need to use a version > 1.0.0; I tested with OpenSSL 1.0.1c 10 May 2012. 34 35 # Testing 36 37 To run the tests, do 38 39 ```bash 40 $ npm test 41 ``` 42 43 This will generate a bunch of keypairs to use in testing. If you want to 44 generate new keypairs, do `make clean` before running `npm test` again. 45 46 ## Methodology 47 48 I spawn `openssl dgst -sign` to test OpenSSL sign → JS verify and 49 `openssl dgst -verify` to test JS sign → OpenSSL verify for each of the 50 RSA and ECDSA algorithms. 51 52 # Usage 53 54 ## jwa(algorithm) 55 56 Creates a new `jwa` object with `sign` and `verify` methods for the 57 algorithm. Valid values for algorithm can be found in the table above 58 (`'HS256'`, `'HS384'`, etc) and are case-insensitive. Passing an invalid 59 algorithm value will throw a `TypeError`. 60 61 62 ## jwa#sign(input, secretOrPrivateKey) 63 64 Sign some input with either a secret for HMAC algorithms, or a private 65 key for RSA and ECDSA algorithms. 66 67 If input is not already a string or buffer, `JSON.stringify` will be 68 called on it to attempt to coerce it. 69 70 For the HMAC algorithm, `secretOrPrivateKey` should be a string or a 71 buffer. For ECDSA and RSA, the value should be a string representing a 72 PEM encoded **private** key. 73 74 Output [base64url](http://en.wikipedia.org/wiki/Base64#URL_applications) 75 formatted. This is for convenience as JWS expects the signature in this 76 format. If your application needs the output in a different format, 77 [please open an issue](https://github.com/brianloveswords/node-jwa/issues). In 78 the meantime, you can use 79 [brianloveswords/base64url](https://github.com/brianloveswords/base64url) 80 to decode the signature. 81 82 As of nodejs *v0.11.8*, SPKAC support was introduce. If your nodeJs 83 version satisfies, then you can pass an object `{ key: '..', passphrase: '...' }` 84 85 86 ## jwa#verify(input, signature, secretOrPublicKey) 87 88 Verify a signature. Returns `true` or `false`. 89 90 `signature` should be a base64url encoded string. 91 92 For the HMAC algorithm, `secretOrPublicKey` should be a string or a 93 buffer. For ECDSA and RSA, the value should be a string represented a 94 PEM encoded **public** key. 95 96 97 # Example 98 99 HMAC 100 ```js 101 const jwa = require('jwa'); 102 103 const hmac = jwa('HS256'); 104 const input = 'super important stuff'; 105 const secret = 'shhhhhh'; 106 107 const signature = hmac.sign(input, secret); 108 hmac.verify(input, signature, secret) // === true 109 hmac.verify(input, signature, 'trickery!') // === false 110 ``` 111 112 With keys 113 ```js 114 const fs = require('fs'); 115 const jwa = require('jwa'); 116 const privateKey = fs.readFileSync(__dirname + '/ecdsa-p521-private.pem'); 117 const publicKey = fs.readFileSync(__dirname + '/ecdsa-p521-public.pem'); 118 119 const ecdsa = jwa('ES512'); 120 const input = 'very important stuff'; 121 122 const signature = ecdsa.sign(input, privateKey); 123 ecdsa.verify(input, signature, publicKey) // === true 124 ``` 125 ## License 126 127 MIT 128 129 ``` 130 Copyright (c) 2013 Brian J. Brennan 131 132 Permission is hereby granted, free of charge, to any person obtaining a 133 copy of this software and associated documentation files (the 134 "Software"), to deal in the Software without restriction, including 135 without limitation the rights to use, copy, modify, merge, publish, 136 distribute, sublicense, and/or sell copies of the Software, and to 137 permit persons to whom the Software is furnished to do so, subject to 138 the following conditions: 139 140 The above copyright notice and this permission notice shall be included 141 in all copies or substantial portions of the Software. 142 143 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 144 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 145 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 146 NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 147 LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 148 OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 149 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 150 ```