1# node-jose #
2
3[![Greenkeeper badge](https://badges.greenkeeper.io/cisco/node-jose.svg)](https://greenkeeper.io/)
4[![Build Status](https://travis-ci.org/cisco/node-jose.svg?branch=master)](https://travis-ci.org/cisco/node-jose)
5
6A JavaScript implementation of the JSON Object Signing and Encryption (JOSE) for current web browsers and node.js-based servers.  This library implements (wherever possible) all algorithms, formats, and options in [JWS](https://tools.ietf.org/html/rfc7515 "Jones, M., J. Bradley and N. Sakimura, 'JSON Web Signature (JWS)' RFC 7515, May 2015"), [JWE](https://tools.ietf.org/html/rfc7516 "Jones, M. and J. Hildebrand 'JSON Web Encryption (JWE)', RFC 7516, May 2015"), [JWK](https://tools.ietf.org/html/rfc7517 "Jones, M., 'JSON Web Key (JWK)', RFC 7517, May 2015"), and [JWA](https://tools.ietf.org/html/rfc7518 "Jones, M., 'JSON Web Algorithms (JWA)', RFC 7518, May 2015") and uses native cryptographic support ([WebCrypto API](http://www.w3.org/TR/WebCryptoAPI/) or node.js' "[crypto](https://nodejs.org/api/crypto.html)" module) where feasible.
7
8<!-- START doctoc generated TOC please keep comment here to allow auto update -->
9<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
10
11
12- [Installing](#installing)
13- [Basics](#basics)
14- [Keys and Key Stores](#keys-and-key-stores)
15  - [Obtaining a KeyStore](#obtaining-a-keystore)
16  - [Exporting a KeyStore](#exporting-a-keystore)
17  - [Retrieving Keys](#retrieving-keys)
18  - [Searching for Keys](#searching-for-keys)
19  - [Managing Keys](#managing-keys)
20  - [Importing and Exporting a Single Key](#importing-and-exporting-a-single-key)
21  - [Obtaining a Key's Thumbprint](#obtaining-a-keys-thumbprint)
22- [Signatures](#signatures)
23  - [Keys Used for Signing and Verifying](#keys-used-for-signing-and-verifying)
24  - [Signing Content](#signing-content)
25  - [Verifying a JWS](#verifying-a-jws)
26    - [Allowing (or Disallowing) Signature Algorithms](#allowing-or-disallowing-signature-algorithms)
27    - [Handling `crit` Header Members](#handling-crit-header-members)
28- [Encryption](#encryption)
29  - [Keys Used for Encrypting and Decrypting](#keys-used-for-encrypting-and-decrypting)
30  - [Encrypting Content](#encrypting-content)
31  - [Decrypting a JWE](#decrypting-a-jwe)
32    - [Allowing (or Disallowing) Encryption Algorithms](#allowing-or-disallowing-encryption-algorithms)
33    - [Handling `crit` Header Members](#handling-crit-header-members-1)
34- [Useful Utilities](#useful-utilities)
35  - [Converting to Buffer](#converting-to-buffer)
36  - [URI-Safe Base64](#uri-safe-base64)
37  - [Random Bytes](#random-bytes)
38
39<!-- END doctoc generated TOC please keep comment here to allow auto update -->
40
41## Installing ##
42
43To install the latest from [NPM](https://npmjs.com/):
44
45```shell
46  npm install node-jose
47```
48
49Or to install a specific release:
50
51```shell
52  npm install node-jose@0.3.0
53```
54
55Alternatively, the latest unpublished code can be installed directly from the repository:
56
57```shell
58  npm install git+https://github.com/cisco/node-jose.git
59```
60
61## Basics ##
62
63Require the library as normal:
64
65```javascript
66var jose = require('node-jose');
67```
68
69This library uses [Promises](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) for nearly every operation.
70
71This library supports [Browserify](http://browserify.org/) and [Webpack](https://webpack.github.io/).  To use in a web browser, `require('node-jose')` and bundle with the rest of your app.
72
73The content to be signed/encrypted -- or returned from being verified/decrypted -- are [Buffer](https://nodejs.org/api/buffer.html) objects.
74
75## Keys and Key Stores ##
76
77The `jose.JWK` namespace deals with JWK and JWK-sets.
78
79* `jose.JWK.Key` is a logical representation of a JWK, and is the "raw" entry point for various cryptographic operations (e.g., sign, verify, encrypt, decrypt).
80* `jose.JWK.KeyStore` represents a collection of Keys.
81
82Creating a JWE or JWS ultimately require one or more explicit Key objects.
83
84Processing a JWE or JWS relies on a KeyStore.
85
86### Obtaining a KeyStore ###
87To create an empty keystore:
88
89```javascript
90keystore = jose.JWK.createKeyStore();
91```
92
93To import a JWK-set as a keystore:
94
95```javascript
96// {input} is a String or JSON object representing the JWK-set
97jose.JWK.asKeyStore(input).
98     then(function(result) {
99       // {result} is a jose.JWK.KeyStore
100       keystore = result;
101     });
102```
103
104### Exporting a KeyStore ###
105
106To export the public keys of a keystore as a JWK-set:
107
108```javascript
109output = keystore.toJSON();
110```
111
112To export **all** the keys of a keystore:
113
114```javascript
115output = keystore.toJSON(true);
116```
117
118### Retrieving Keys ###
119
120To retrieve a key from a keystore:
121
122```javascript
123// by 'kid'
124key = keystore.get(kid);
125```
126
127This retrieves the first key that matches the given {kid}.  If multiple keys have the same {kid}, you can further narrow what to retrieve:
128
129```javascript
130// ... and by 'kty'
131key = keystore.get(kid, { kty: 'RSA' });
132
133// ... and by 'use'
134key = keystore.get(kid, { use: 'enc' });
135
136// ... and by 'alg'
137key = keystore.get(kid, { use: 'RSA-OAEP' });
138
139// ... and by 'kty' and 'use'
140key = keystore.get(kid, { kty: 'RSA', use: 'enc' });
141
142// same as above, but with a single {props} argument
143key = keystore.get({ kid: kid, kty: 'RSA', use: 'enc' });
144```
145
146### Searching for Keys ###
147
148To retrieve all the keys from a keystore:
149
150```javascript
151everything = keystore.all();
152```
153
154`all()` can be filtered much like `get()`:
155
156```javascript
157// filter by 'kid'
158everything = keystore.all({ kid: kid });
159
160// filter by 'kty'
161everything = keystore.all({ kty: 'RSA' });
162
163// filter by 'use'
164everything = keystore.all({ use: 'enc' });
165
166// filter by 'alg'
167everything = keystore.all({ alg: 'RSA-OAEP' });
168
169// filter by 'kid' + 'kty' + 'alg'
170everything = keystore.all({ kid: kid, kty: 'RSA', alg: 'RSA-OAEP' });
171```
172
173### Managing Keys ###
174
175To import an existing Key (as a JSON object or Key instance):
176
177```javascript
178// input is either a:
179// *  jose.JWK.Key to copy from; or
180// *  JSON object representing a JWK; or
181keystore.add(input).
182        then(function(result) {
183          // {result} is a jose.JWK.Key
184          key = result;
185        });
186```
187
188To import and existing Key from a PEM or DER:
189
190```javascript
191// input is either a:
192// *  String serialization of a JSON JWK/(base64-encoded) PEM/(binary-encoded) DER
193// *  Buffer of a JSON JWK/(base64-encoded) PEM/(binary-encoded) DER
194// form is either a:
195// * "json" for a JSON stringified JWK
196// * "private" for a DER encoded 'raw' private key
197// * "pkcs8" for a DER encoded (unencrypted!) PKCS8 private key
198// * "public" for a DER encoded SPKI public key (alternate to 'spki')
199// * "spki" for a DER encoded SPKI public key
200// * "pkix" for a DER encoded PKIX X.509 certificate
201// * "x509" for a DER encoded PKIX X.509 certificate
202// * "pem" for a PEM encoded of PKCS8 / SPKI / PKIX
203keystore.add(input, form).
204        then(function(result) {
205          // {result} is a jose.JWK.Key
206        });
207```
208
209To generate a new Key:
210
211```javascript
212// first argument is the key type (kty)
213// second is the key size (in bits) or named curve ('crv') for "EC"
214keystore.generate("oct", 256).
215        then(function(result) {
216          // {result} is a jose.JWK.Key
217          key = result;
218        });
219
220// ... with properties
221var props = {
222  kid: 'gBdaS-G8RLax2qgObTD94w',
223  alg: 'A256GCM',
224  use: 'enc'
225};
226keystore.generate("oct", 256, props).
227        then(function(result) {
228          // {result} is a jose.JWK.Key
229          key = result;
230        });
231```
232
233To remove a Key from its Keystore:
234```javascript
235keystore.remove(key);
236// NOTE: key.keystore does not change!!
237```
238
239### Importing and Exporting a Single Key ###
240
241To create a single "stand alone" key:
242
243```javascript
244jose.JWK.createKey("oct", 256, { alg: "A256GCM" }).
245         then(function(result) {
246           // {result} is a jose.JWK.Key
247           // {result.keystore} is a unique jose.JWK.KeyStore
248         });
249```
250
251
252To import a single Key:
253
254```javascript
255// where input is either a:
256// *  jose.JWK.Key instance
257// *  JSON Object representation of a JWK
258jose.JWK.asKey(input).
259        then(function(result) {
260          // {result} is a jose.JWK.Key
261          // {result.keystore} is a unique jose.JWK.KeyStore
262        });
263
264// where input is either a:
265// *  String serialization of a JSON JWK/(base64-encoded) PEM/(binary-encoded) DER
266// *  Buffer of a JSON JWK/(base64-encoded) PEM/(binary-encoded) DER
267// form is either a:
268// * "json" for a JSON stringified JWK
269// * "pkcs8" for a DER encoded (unencrypted!) PKCS8 private key
270// * "spki" for a DER encoded SPKI public key
271// * "pkix" for a DER encoded PKIX X.509 certificate
272// * "x509" for a DER encoded PKIX X.509 certificate
273// * "pem" for a PEM encoded of PKCS8 / SPKI / PKIX
274jose.JWK.asKey(input, form).
275        then(function(result) {
276          // {result} is a jose.JWK.Key
277          // {result.keystore} is a unique jose.JWK.KeyStore
278        });
279```
280
281To export the public portion of a Key as a JWK:
282
283```javascript
284var output = key.toJSON();
285```
286
287To export the public **and** private portions of a Key:
288
289```javascript
290var output = key.toJSON(true);
291```
292
293### Obtaining a Key's Thumbprint ###
294
295To get or calculate a [RFC 7638](https://tools.ietf.org/html/rfc7638) thumbprint for a key:
296
297```javascript
298// where hash is a supported algorithm, currently one of:
299// * SHA-1
300// * SHA-256
301// * SHA-384
302// * SHA-512
303key.thumbprint(hash).
304    then(function(print) {
305      // {print} is a Buffer containing the thumbprint binary value
306    });
307```
308
309When importing or generating a key that does not have a "kid" defined, a
310"SHA-256" thumbprint is calculated and used as the "kid".
311
312## Signatures ##
313
314### Keys Used for Signing and Verifying ###
315
316When signing content, the key is expected to meet one of the following:
317
3181. A secret key (e.g, `"kty":"oct"`)
3192. The **private** key from a PKI (`"kty":"EC"` or `"kty":"RSA"`) key pair
320
321When verifying content, the key is expected to meet one of the following:
322
3231. A secret key (e.g, `"kty":"oct"`)
3242. The **public** key from a PKI (`"kty":"EC"` or `"kty":"RSA"`) key pair
325
326
327### Signing Content ###
328
329At its simplest, to create a JWS:
330
331```javascript
332// {input} is a Buffer
333jose.JWS.createSign(key).
334        update(input).
335        final().
336        then(function(result) {
337          // {result} is a JSON object -- JWS using the JSON General Serialization
338        });
339```
340
341The JWS is signed using the preferred algorithm appropriate for the given Key.  The preferred algorithm is the first item returned by `key.algorithms("sign")`.
342
343To create a JWS using another serialization format:
344
345```javascript
346jose.JWS.createSign({ format: 'flattened' }, key).
347        update(input).
348        final().
349        then(function(result) {
350          // {result} is a JSON object -- JWS using the JSON Flattened Serialization
351        });
352
353jose.JWS.createSign({ format: 'compact' }, key).
354        update(input).
355        final().
356        then(function(result) {
357          // {result} is a String -- JWS using the Compact Serialization
358        });
359```
360
361To create a JWS using a specific algorithm:
362```javascript
363jose.JWS.createSign({ alg: 'PS256' }, key).
364        update(input).
365        final().
366        then(function(result) {
367          // ....
368        });
369```
370
371To create a JWS for a specified content type:
372
373```javascript
374jose.JWS.createSign({ fields: { cty: 'jwk+json' } }, key).
375        update(input).
376        final().
377        then(function(result) {
378          // ....
379        });
380```
381
382To create a JWS from String content:
383
384```javascript
385jose.JWS.createSign(key).
386        update(input, "utf8").
387        final().
388        then(function(result) {
389          // ....
390        });
391```
392
393To create a JWS with multiple signatures:
394
395```javascript
396// {keys} is an Array of jose.JWK.Key instances
397jose.JWS.createSign(keys).
398        update(input).
399        final().
400        then(function(result) {
401          // ....
402        });
403```
404
405### Verifying a JWS ###
406
407To verify a JWS, and retrieve the payload:
408
409```javascript
410jose.JWS.createVerify(keystore).
411        verify(input).
412        then(function(result) {
413          // {result} is a Object with:
414          // *  header: the combined 'protected' and 'unprotected' header members
415          // *  payload: Buffer of the signed content
416          // *  signature: Buffer of the verified signature
417          // *  key: The key used to verify the signature
418        });
419```
420
421To verify using an implied Key:
422
423```javascript
424// {key} can be:
425// *  jose.JWK.Key
426// *  JSON object representing a JWK
427jose.JWS.createVerify(key).
428        verify(input).
429        then(function(result) {
430          // ...
431        });
432```
433
434To verify using a key embedded in the JWS:
435
436```javascript
437jose.JWS.createVerify().
438        verify(input, { allowEmbeddedKey: true }).
439        then(function(result) {
440          // ...
441        });
442```
443
444Alternatively, a cached `createVerify()` can be configured to allow an embedded key:
445
446```javascript
447var verifier = jose.JWS.createVerify({ allowEmbeddedKey: true });
448
449verifier.verify(input).
450         then(function(result) {
451           // ...
452         });
453```
454
455The key can be embedded using either 'jwk' or 'x5c', and can be located in either the JWS Unprotected Header or JWS Protected Header.
456
457**NOTE:** `verify()` will use the embedded key (if found and permitted) instead of any other key.
458
459#### Allowing (or Disallowing) Signature Algorithms ###
460
461To restrict what signature algorithms are allowed when verifying, add the `allowAlgs` member to the `options` Object.  The `allowAlgs` member is either a string or an array of strings, where the string value(s) can be one of the following:
462
463* `"*"`: accept all supported algorithms
464* **`<alg name>`** (e.g., `"PS256"`): accept the specific algorithm (can have a single '*' to match a range of algorithms)
465* **`!<alg name>`** (e.g., `"!RS256"`): *do not* accept the specific algorithm (can have a single '*' to match a range of algorithms)
466
467The negation is intended to be used with the wildcard accept string, and disallow takes precedence over allowed.
468
469To only accept RSA-PSS sigatures:
470
471```javascript
472var opts = {
473  algorithms: ["PS*"]
474};
475jose.JWS.createVerify(key, opts).
476        verify(input).
477        then(function(result) {
478          // ...
479        });
480```
481
482To accept any algorithm, but disallow HMAC-based signatures:
483
484```javascript
485var opts = {
486  algorithms: ["*", "!HS*"]
487};
488jose.JWS.createVerify(key, opts).
489        verify(input).
490        then(input).
491        then(function(result) {
492          // ...
493        });
494```
495
496#### Handling `crit` Header Members ####
497
498To accept 'crit' field members, add the `handlers` member to the options Object.  The `handlers` member is itself an Object, where its member names are the `crit` header member, and the value is one of:
499
500* `Boolean`: accepts (if `true`) -- or rejects (if `false`) -- the JWS if the member is present.
501* `Function`: takes the JWE decrypt output (just prior to decrypting) and returns a Promise for the processing of the member.
502* `Object`: An object with the following `Function` members:
503  * "prepare" -- takes the JWE decrypt output (just prior to decrypting) and returns a Promise for the processing of the member.
504  * "complete" -- takes the JWE decrypt output (immediately after decrypting) and returns a Promise for the processing of the member.
505
506**NOTE** If the handler function returns a promise, the fulfilled value is ignored.  It is expected these handler functions will modify the provided value directly.
507
508To simply accept a `crit` header member:
509
510```javascript
511var opts = {
512  handlers: {
513    "exp": true
514  }
515};
516jose.JWS.createVerify(key, opts).
517        verify(input).
518        then(function(result) {
519          // ...
520        });
521```
522
523To perform additional (pre-verify) processing on a `crit` header member:
524
525```javascript
526var opts = {
527  handlers: {
528    "exp": function(jws) {
529      // {jws} is the JWS verify output, pre-verification
530      jws.header.exp = new Date(jws.header.exp);
531    }
532  }
533};
534jose.JWS.createVerify(key, opts).
535        verify(input).
536        then(function(result) {
537          // ...
538        });
539```
540
541To perform additional (post-verify) processing on a `crit` header member:
542
543```javascript
544var opts = {
545  handlers: {
546    "exp": {
547      complete: function(jws) {
548        // {jws} is the JWS verify output, post-verification
549        jws.header.exp = new Date(jws.header.exp);
550      }
551    }
552  }
553};
554jose.JWS.createVerify(key, opts).
555        verify(input).
556        then(function(result) {
557          // ...
558        });
559```
560
561
562## Encryption ##
563
564
565### Keys Used for Encrypting and Decrypting ###
566
567When encrypting content, the key is expected to meet one of the following:
568
5691. A secret key (e.g, `"kty":"oct"`)
5702. The **public** key from a PKI (`"kty":"EC"` or `"kty":"RSA"`) key pair
571
572When decrypting content, the key is expected to meet one of the following:
573
5741. A secret key (e.g, `"kty":"oct"`)
5752. The **private** key from a PKI (`"kty":"EC"` or `"kty":"RSA"`) key pair
576
577
578### Encrypting Content ###
579
580At its simplest, to create a JWE:
581
582```javascript
583// {input} is a Buffer
584jose.JWE.createEncrypt(key).
585        update(input).
586        final().
587        then(function(result) {
588          // {result} is a JSON Object -- JWE using the JSON General Serialization
589        });
590```
591
592How the JWE content is encrypted depends on the provided Key.
593
594* If the Key only supports content encryption algorithms, then the preferred algorithm is used to encrypt the content and the key encryption algorithm (i.e., the "alg" member) is set to "dir".  The preferred algorithm is the first item returned by `key.algorithms("encrypt")`.
595* If the Key supports key management algorithms, then the JWE content is encrypted using "A128CBC-HS256" by default, and the Content Encryption Key is encrypted using the preferred algorithms for the given Key.  The preferred algorithm is the first item returned by `key.algorithms("wrap")`.
596
597
598To create a JWE using a different serialization format:
599
600```javascript
601jose.JWE.createEncrypt({ format: 'compact' }, key).
602        update(input).
603        final().
604        then(function(result) {
605          // {result} is a String -- JWE using the Compact Serialization
606        });
607
608jose.JWE.createEncrypt({ format: 'flattened' }, key).
609        update(input).
610        final().
611        then(function(result) {
612          // {result} is a JSON Object -- JWE using the JSON Flattened Serialization
613        });
614```
615
616To create a JWE and compressing the content before encrypting:
617
618```javascript
619jose.JWE.createEncrypt({ zip: true }, key).
620        update(input).
621        final().
622        then(function(result) {
623          // ....
624        });
625```
626
627To create a JWE for a specific content type:
628
629```javascript
630jose.JWE.createEncrypt({ fields: { cty : 'jwk+json' } }, key).
631        update(input).
632        final().
633        then(function(result) {
634          // ....
635        });
636```
637
638To create a JWE with multiple recipients:
639
640```javascript
641// {keys} is an Array of jose.JWK.Key instances
642jose.JWE.createEncrypt(keys).
643        update(input).
644        final().
645        then(function(result) {
646          // ....
647        });
648```
649
650### Decrypting a JWE ###
651
652To decrypt a JWE, and retrieve the plaintext:
653
654```javascript
655jose.JWE.createDecrypt(keystore).
656        decrypt(input).
657        then(function(result) {
658          // {result} is a Object with:
659          // *  header: the combined 'protected' and 'unprotected' header members
660          // *  protected: an array of the member names from the "protected" member
661          // *  key: Key used to decrypt
662          // *  payload: Buffer of the decrypted content
663          // *  plaintext: Buffer of the decrypted content (alternate)
664        });
665```
666
667To decrypt a JWE using an implied key:
668
669```javascript
670jose.JWE.createDecrypt(key).
671        decrypt(input).
672        then(function(result) {
673          // ....
674        });
675```
676
677#### Allowing (or Disallowing) Encryption Algorithms ###
678
679To restrict what encryption algorithms are allowed when verifying, add the `allowAlgs` member to the `options` Object.  The `allowAlgs` member is either a string or an array of strings, where the string value(s) can be one of the following:
680
681* `"*"`: accept all supported algorithms
682* **`<alg name>`** (e.g., `"A128KW"`): accept the specific algorithm (can have a single '*' to match a range of similar algorithms)
683* **`!<alg name>`** (e.g., `"!RSA1_5"`): *do not* accept the specific algorithm (can have a single '*' to match a range of similar algorithms)
684
685The negation is intended to be used with the wildcard accept string, and disallow takes precedence over allowed.
686
687To only accept "dir" and AES-GCM encryption:
688
689```javascript
690var opts = {
691  algorithms: ["dir", "A*GCM"]
692};
693jose.JWE.createDecrypt(key, opts).
694        decrypt(input).
695        then(function(result) {
696          // ...
697        });
698```
699
700To accept any algorithm, but disallow RSA-based encryption:
701
702```javascript
703var opts = {
704  algorithms: ["*", "!RSA*"]
705};
706jose.JWS.createVerify(key, opts).
707        verify(input).
708        then(input).
709        then(function(result) {
710          // ...
711        });
712```
713
714#### Handling `crit` Header Members ####
715
716To accept 'crit' field members, add the `handlers` member to the options Object.  The `handlers` member is itself an Object, where its member names are the `crit` header member, and the value is one of:
717
718* `Boolean`: accepts (if `true`) -- or rejects (if `false`) -- the JWE if the member is present.
719* `Function`: takes the JWE decrypt output (just prior to decrypting) and returns a Promise for the processing of the member.
720* `Object`: An object with the following `Function` members:
721  * "prepare" -- takes the JWE decrypt output (just prior to decrypting) and returns a Promise for the processing of the member.
722  * "complete" -- takes the JWE decrypt output (immediately after decrypting) and returns a Promise for the processing of the member.
723
724**NOTE** If the handler function returns a promise, the fulfilled value is ignored.  It is expected these handler functions will modify the provided value directly.
725
726To simply accept a `crit` header member:
727
728```javascript
729var opts = {
730  handlers: {
731    "exp": true
732  }
733};
734jose.JWE.createDecrypt(key, opts).
735        decrypt(input).
736        then(function(result) {
737          // ...
738        });
739```
740
741To perform additional (pre-decrypt) processing on a `crit` header member:
742
743```javascript
744var opts = {
745  handlers: {
746    "exp": function(jwe) {
747      // {jwe} is the JWE decrypt output, pre-decryption
748      jwe.header.exp = new Date(jwe.header.exp);
749    }
750  }
751};
752jose.JWE.createDecrypt(key, opts).
753        decrypt(input).
754        then(function(result) {
755          // ...
756        });
757```
758
759To perform additional (post-decrypt) processing on a `crit` header member:
760
761```javascript
762var opts = {
763  handlers: {
764    "exp": {
765      complete: function(jwe) {
766        // {jwe} is the JWE decrypt output, post-decryption
767        jwe.header.exp = new Date(jwe.header.exp);
768      }
769    }
770  }
771};
772jose.JWE.createDecrypt(key, opts).
773        decrypt(input).
774        then(function(result) {
775          // ...
776        });
777```
778
779## Useful Utilities ##
780
781### Converting to Buffer ###
782
783To convert a [Typed Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Typed_arrays), [ArrayBuffer](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/ArrayBuffer), or Array of Numbers to a Buffer:
784
785```javascript
786buff = jose.util.asBuffer(input);
787```
788
789### URI-Safe Base64 ###
790
791This exposes [urlsafe-base64](https://github.com/RGBboy/urlsafe-base64)'s `encode` and `decode` methods as `encode` and `decode` (respectively).
792
793To convert from a Buffer to a base64uri-encoded String:
794
795```javascript
796var output = jose.util.base64url.encode(input);
797```
798
799To convert a String to a base64uri-encoded String:
800
801```javascript
802// explicit encoding
803output = jose.util.base64url.encode(input, "utf8");
804
805// implied "utf8" encoding
806output = jose.util.base64url.encode(input);
807```
808
809To convert a base64uri-encoded String to a Buffer:
810
811```javascript
812var output = jose.util.base64url.decode(input);
813```
814
815### Random Bytes ###
816
817To generate a Buffer of octets, regardless of platform:
818
819```javascript
820// argument is size (in bytes)
821var rnd = jose.util.randomBytes(32);
822```
823
824This function uses:
825
826* `crypto.randomBytes()` on node.js
827* `crypto.getRandomValues()` on modern browsers
828* A PRNG based on AES and SHA-1 for older platforms
829