You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					256 lines
				
				6.8 KiB
			
		
		
			
		
	
	
					256 lines
				
				6.8 KiB
			| 
											3 years ago
										 | # node-jws [](http://travis-ci.org/brianloveswords/node-jws)
 | ||
|  | 
 | ||
|  | An implementation of [JSON Web Signatures](http://self-issued.info/docs/draft-ietf-jose-json-web-signature.html). | ||
|  | 
 | ||
|  | This was developed against `draft-ietf-jose-json-web-signature-08` and | ||
|  | implements the entire spec **except** X.509 Certificate Chain | ||
|  | signing/verifying (patches welcome). | ||
|  | 
 | ||
|  | There are both synchronous (`jws.sign`, `jws.verify`) and streaming | ||
|  | (`jws.createSign`, `jws.createVerify`) APIs. | ||
|  | 
 | ||
|  | # Install
 | ||
|  | 
 | ||
|  | ```bash | ||
|  | $ npm install jws | ||
|  | ``` | ||
|  | 
 | ||
|  | # Usage
 | ||
|  | 
 | ||
|  | ## jws.ALGORITHMS
 | ||
|  | 
 | ||
|  | Array of supported algorithms. The following algorithms are currently supported. | ||
|  | 
 | ||
|  | alg Parameter Value | Digital Signature or MAC Algorithm | ||
|  | ----------------|---------------------------- | ||
|  | HS256 | HMAC using SHA-256 hash algorithm | ||
|  | HS384 | HMAC using SHA-384 hash algorithm | ||
|  | HS512 | HMAC using SHA-512 hash algorithm | ||
|  | RS256 | RSASSA using SHA-256 hash algorithm | ||
|  | RS384 | RSASSA using SHA-384 hash algorithm | ||
|  | RS512 | RSASSA using SHA-512 hash algorithm | ||
|  | PS256 | RSASSA-PSS using SHA-256 hash algorithm | ||
|  | PS384 | RSASSA-PSS using SHA-384 hash algorithm | ||
|  | PS512 | RSASSA-PSS using SHA-512 hash algorithm | ||
|  | ES256 | ECDSA using P-256 curve and SHA-256 hash algorithm | ||
|  | ES384 | ECDSA using P-384 curve and SHA-384 hash algorithm | ||
|  | ES512 | ECDSA using P-521 curve and SHA-512 hash algorithm | ||
|  | none | No digital signature or MAC value included | ||
|  | 
 | ||
|  | ## jws.sign(options)
 | ||
|  | 
 | ||
|  | (Synchronous) Return a JSON Web Signature for a header and a payload. | ||
|  | 
 | ||
|  | Options: | ||
|  | 
 | ||
|  | * `header` | ||
|  | * `payload` | ||
|  | * `secret` or `privateKey` | ||
|  | * `encoding` (Optional, defaults to 'utf8') | ||
|  | 
 | ||
|  | `header` must be an object with an `alg` property. `header.alg` must be | ||
|  | one a value found in `jws.ALGORITHMS`. See above for a table of | ||
|  | supported algorithms. | ||
|  | 
 | ||
|  | If `payload` is not a buffer or a string, it will be coerced into a string | ||
|  | using `JSON.stringify`. | ||
|  | 
 | ||
|  | Example | ||
|  | 
 | ||
|  | ```js | ||
|  | const signature = jws.sign({ | ||
|  |   header: { alg: 'HS256' }, | ||
|  |   payload: 'h. jon benjamin', | ||
|  |   secret: 'has a van', | ||
|  | }); | ||
|  | ``` | ||
|  | 
 | ||
|  | ## jws.verify(signature, algorithm, secretOrKey)
 | ||
|  | 
 | ||
|  | (Synchronous) Returns `true` or `false` for whether a signature matches a | ||
|  | secret or key. | ||
|  | 
 | ||
|  | `signature` is a JWS Signature. `header.alg` must be a value found in `jws.ALGORITHMS`. | ||
|  | See above for a table of supported algorithms. `secretOrKey` is a string or | ||
|  | buffer containing either the secret for HMAC algorithms, or the PEM | ||
|  | encoded public key for RSA and ECDSA. | ||
|  | 
 | ||
|  | Note that the `"alg"` value from the signature header is ignored. | ||
|  | 
 | ||
|  | 
 | ||
|  | ## jws.decode(signature)
 | ||
|  | 
 | ||
|  | (Synchronous) Returns the decoded header, decoded payload, and signature | ||
|  | parts of the JWS Signature. | ||
|  | 
 | ||
|  | Returns an object with three properties, e.g. | ||
|  | ```js | ||
|  | { header: { alg: 'HS256' }, | ||
|  |   payload: 'h. jon benjamin', | ||
|  |   signature: 'YOWPewyGHKu4Y_0M_vtlEnNlqmFOclqp4Hy6hVHfFT4' | ||
|  | } | ||
|  | ``` | ||
|  | 
 | ||
|  | ## jws.createSign(options)
 | ||
|  | 
 | ||
|  | Returns a new SignStream object. | ||
|  | 
 | ||
|  | Options: | ||
|  | 
 | ||
|  | * `header` (required) | ||
|  | * `payload` | ||
|  | * `key` || `privateKey` || `secret` | ||
|  | * `encoding` (Optional, defaults to 'utf8') | ||
|  | 
 | ||
|  | Other than `header`, all options expect a string or a buffer when the | ||
|  | value is known ahead of time, or a stream for convenience. | ||
|  | `key`/`privateKey`/`secret` may also be an object when using an encrypted | ||
|  | private key, see the [crypto documentation][encrypted-key-docs]. | ||
|  | 
 | ||
|  | Example: | ||
|  | 
 | ||
|  | ```js | ||
|  | 
 | ||
|  | // This... | ||
|  | jws.createSign({ | ||
|  |   header: { alg: 'RS256' }, | ||
|  |   privateKey: privateKeyStream, | ||
|  |   payload: payloadStream, | ||
|  | }).on('done', function(signature) { | ||
|  |   // ... | ||
|  | }); | ||
|  | 
 | ||
|  | // is equivalent to this: | ||
|  | const signer = jws.createSign({ | ||
|  |   header: { alg: 'RS256' }, | ||
|  | }); | ||
|  | privateKeyStream.pipe(signer.privateKey); | ||
|  | payloadStream.pipe(signer.payload); | ||
|  | signer.on('done', function(signature) { | ||
|  |   // ... | ||
|  | }); | ||
|  | ``` | ||
|  | 
 | ||
|  | ## jws.createVerify(options)
 | ||
|  | 
 | ||
|  | Returns a new VerifyStream object. | ||
|  | 
 | ||
|  | Options: | ||
|  | 
 | ||
|  | * `signature` | ||
|  | * `algorithm` | ||
|  | * `key` || `publicKey` || `secret` | ||
|  | * `encoding` (Optional, defaults to 'utf8') | ||
|  | 
 | ||
|  | All options expect a string or a buffer when the value is known ahead of | ||
|  | time, or a stream for convenience. | ||
|  | 
 | ||
|  | Example: | ||
|  | 
 | ||
|  | ```js | ||
|  | 
 | ||
|  | // This... | ||
|  | jws.createVerify({ | ||
|  |   publicKey: pubKeyStream, | ||
|  |   signature: sigStream, | ||
|  | }).on('done', function(verified, obj) { | ||
|  |   // ... | ||
|  | }); | ||
|  | 
 | ||
|  | // is equivilant to this: | ||
|  | const verifier = jws.createVerify(); | ||
|  | pubKeyStream.pipe(verifier.publicKey); | ||
|  | sigStream.pipe(verifier.signature); | ||
|  | verifier.on('done', function(verified, obj) { | ||
|  |   // ... | ||
|  | }); | ||
|  | ``` | ||
|  | 
 | ||
|  | ## Class: SignStream
 | ||
|  | 
 | ||
|  | A `Readable Stream` that emits a single data event (the calculated | ||
|  | signature) when done. | ||
|  | 
 | ||
|  | ### Event: 'done'
 | ||
|  | `function (signature) { }` | ||
|  | 
 | ||
|  | ### signer.payload
 | ||
|  | 
 | ||
|  | A `Writable Stream` that expects the JWS payload. Do *not* use if you | ||
|  | passed a `payload` option to the constructor. | ||
|  | 
 | ||
|  | Example: | ||
|  | 
 | ||
|  | ```js | ||
|  | payloadStream.pipe(signer.payload); | ||
|  | ``` | ||
|  | 
 | ||
|  | ### signer.secret<br>signer.key<br>signer.privateKey
 | ||
|  | 
 | ||
|  | A `Writable Stream`. Expects the JWS secret for HMAC, or the privateKey | ||
|  | for ECDSA and RSA. Do *not* use if you passed a `secret` or `key` option | ||
|  | to the constructor. | ||
|  | 
 | ||
|  | Example: | ||
|  | 
 | ||
|  | ```js | ||
|  | privateKeyStream.pipe(signer.privateKey); | ||
|  | ``` | ||
|  | 
 | ||
|  | ## Class: VerifyStream
 | ||
|  | 
 | ||
|  | This is a `Readable Stream` that emits a single data event, the result | ||
|  | of whether or not that signature was valid. | ||
|  | 
 | ||
|  | ### Event: 'done'
 | ||
|  | `function (valid, obj) { }` | ||
|  | 
 | ||
|  | `valid` is a boolean for whether or not the signature is valid. | ||
|  | 
 | ||
|  | ### verifier.signature
 | ||
|  | 
 | ||
|  | A `Writable Stream` that expects a JWS Signature. Do *not* use if you | ||
|  | passed a `signature` option to the constructor. | ||
|  | 
 | ||
|  | ### verifier.secret<br>verifier.key<br>verifier.publicKey
 | ||
|  | 
 | ||
|  | A `Writable Stream` that expects a public key or secret. Do *not* use if you | ||
|  | passed a `key` or `secret` option to the constructor. | ||
|  | 
 | ||
|  | # TODO
 | ||
|  | 
 | ||
|  | * It feels like there should be some convenience options/APIs for | ||
|  |   defining the algorithm rather than having to define a header object | ||
|  |   with `{ alg: 'ES512' }` or whatever every time. | ||
|  | 
 | ||
|  | * X.509 support, ugh | ||
|  | 
 | ||
|  | # License
 | ||
|  | 
 | ||
|  | MIT | ||
|  | 
 | ||
|  | ``` | ||
|  | Copyright (c) 2013-2015 Brian J. Brennan | ||
|  | 
 | ||
|  | Permission is hereby granted, free of charge, to any person obtaining a | ||
|  | copy of this software and associated documentation files (the | ||
|  | "Software"), to deal in the Software without restriction, including | ||
|  | without limitation the rights to use, copy, modify, merge, publish, | ||
|  | distribute, sublicense, and/or sell copies of the Software, and to | ||
|  | permit persons to whom the Software is furnished to do so, subject to | ||
|  | the following conditions: | ||
|  | 
 | ||
|  | The above copyright notice and this permission notice shall be included | ||
|  | in all copies or substantial portions of the Software. | ||
|  | 
 | ||
|  | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS | ||
|  | OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
|  | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
|  | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE | ||
|  | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION | ||
|  | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION | ||
|  | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
|  | ``` | ||
|  | 
 | ||
|  | [encrypted-key-docs]: https://nodejs.org/api/crypto.html#crypto_sign_sign_private_key_output_format |