1 | # isomorphic-webcrypto [![NPM](https://img.shields.io/npm/v/isomorphic-webcrypto.svg)](https://npmjs.com/package/isomorphic-webcrypto) [![bundlephobia](https://img.shields.io/bundlephobia/minzip/isomorphic-webcrypto.svg)](https://bundlephobia.com/result?p=isomorphic-webcrypto)
|
2 | webcrypto library for Node, React Native and IE11+
|
3 |
|
4 | ## What?
|
5 |
|
6 | There's [a great Node polyfill](https://github.com/PeculiarVentures/webcrypto) for the [Web Crypto API](https://developer.mozilla.org/en-US/docs/Web/API/Web_Crypto_API), but it's not isomorphic.
|
7 |
|
8 | IE11 and versions of Safari < 11 use an older version of the spec, so the browser implementation includes a [webcrypto-shim](https://github.com/vibornoff/webcrypto-shim) to iron out the differences. You'll still need to provide your own Promise polyfill.
|
9 |
|
10 | There's currently no native crypto support in React Native, so [the Microsoft Research library](https://github.com/kevlened/msrCrypto) is exposed.
|
11 |
|
12 | > **Note:** If you're performing cross-platform jwt operations, consider [jwt-lite](https://www.npmjs.com/package/jwt-lite) or [jwt-verifier-lite](https://www.npmjs.com/package/jwt-verifier-lite) (for OpenID Connect), which build on `isomorphic-webcrypto`
|
13 |
|
14 | ## Install
|
15 |
|
16 | `npm install isomorphic-webcrypto`
|
17 |
|
18 | ## Usage
|
19 |
|
20 | There's a simple hashing example below, but [there are many more WebCrypto examples here](https://github.com/diafygi/webcrypto-examples). This example requires you to `npm install hex-lite`.
|
21 |
|
22 | ```javascript
|
23 | const crypto = require('isomorphic-webcrypto')
|
24 | const hex = require('hex-lite')
|
25 | // or
|
26 | import crypto from 'isomorphic-webcrypto'
|
27 | import hex from 'hex-lite'
|
28 |
|
29 | crypto.subtle.digest(
|
30 | { name: 'SHA-256' },
|
31 | new Uint8Array([1,2,3]).buffer
|
32 | )
|
33 | .then(hash => {
|
34 | // hashes are usually represented as hex strings
|
35 | // hex-lite makes this easier
|
36 | const hashString = hex.fromBuffer(hash);
|
37 | })
|
38 | ```
|
39 |
|
40 | ### React Native
|
41 |
|
42 | React Native support is implemented using [the Microsoft Research library](https://github.com/kevlened/msrCrypto). The React Native environment only supports `Math.random()`, so [react-native-securerandom](https://github.com/rh389/react-native-securerandom) is used to provide proper entropy. This is handled automatically, except for `crypto.getRandomValues()`, which requires you wait:
|
43 |
|
44 | ```javascript
|
45 | const crypto = require('isomorphic-webcrypto')
|
46 |
|
47 | (async () => {
|
48 | // Only needed for crypto.getRandomValues
|
49 | // but only wait once, future calls are secure
|
50 | await crypto.ensureSecure();
|
51 | const array = new Uint8Array(1);
|
52 | crypto.getRandomValues(array);
|
53 | const safeValue = array[0];
|
54 | })()
|
55 | ```
|
56 |
|
57 | Working React Native examples:
|
58 |
|
59 | * Using [create-react-native-app](https://github.com/kevlened/webcrypto-react-native-examples/tree/master/crna) with Expo
|
60 | * Using an ejected [create-react-native-app](https://github.com/kevlened/webcrypto-react-native-examples/blob/master/crna-ejected)
|
61 |
|
62 | ## I just want to drop in a script tag
|
63 |
|
64 | You should use [the webcrypto-shim](https://github.com/vibornoff/webcrypto-shim) library directly:
|
65 |
|
66 | ```html
|
67 | <!-- Any Promise polyfill will do -->
|
68 | <script src="https://unpkg.com/bluebird"></script>
|
69 | <script src="https://unpkg.com/webcrypto-shim"></script>
|
70 | ```
|
71 |
|
72 | ## Compatibility
|
73 |
|
74 | * IE11+
|
75 | * Safari 8+
|
76 | * Edge 12+
|
77 | * Chrome 43+
|
78 | * Opera 24+
|
79 | * Firefox 34+
|
80 | * Node 8+
|
81 | * React Native
|
82 |
|
83 | Although the library runs on IE11+, the level of functionality varies between implementations. The grid below shows the discrepancies between the latest versions of each environment.
|
84 |
|
85 | > __Legend__
|
86 | >
|
87 | > * **~** works with some caveats - see the \_\_tests__ directory for the caveats
|
88 | > * **?** untested
|
89 | > * **x** unsupported algorithm
|
90 | > * **strikethrough** broken method
|
91 |
|
92 | | Key | Node | React Native | Chrome/Firefox | Safari | Edge | IE11 |
|
93 | | ------------------ | ----------------------------------------------------------- | ----------------------------------------------------------- | ------------------------------------------------------- | ----------------------------------------------------------- | ------------------------------------------------------------- | --------------------------------------------------------------- |
|
94 | | HS256 | importKey<br>exportKey<br>generateKey<br>sign<br>verify | importKey<br>exportKey<br>generateKey<br>sign<br>verify | importKey<br>exportKey<br>generateKey<br>sign<br>verify | importKey<br>exportKey<br>generateKey<br>sign<br>verify | importKey<br>exportKey<br>generateKey<br>sign<br>verify | importKey<br>exportKey<br>generateKey<br>sign<br>verify |
|
95 | | HS384 | importKey<br>exportKey<br>generateKey<br>sign<br>verify | importKey<br>exportKey<br>generateKey<br>sign<br>verify | importKey<br>exportKey<br>generateKey<br>sign<br>verify | importKey<br>exportKey<br>generateKey<br>sign<br>verify | importKey<br>exportKey<br>generateKey<br>sign<br>verify | importKey<br>exportKey<br>generateKey<br>sign<br>verify |
|
96 | | HS512 | importKey<br>exportKey<br>generateKey<br>sign<br>verify | importKey<br>exportKey<br>generateKey<br>sign<br>verify | importKey<br>exportKey<br>generateKey<br>sign<br>verify | importKey<br>exportKey<br>generateKey<br>sign<br>verify | importKey<br>exportKey<br>generateKey<br>sign<br>verify | x |
|
97 | | RS256 | importKey<br>exportKey<br>generateKey<br>sign<br>verify | importKey<br>exportKey<br>~~generateKey~~<br>sign<br>verify | importKey<br>exportKey<br>generateKey<br>sign<br>verify | importKey<br>exportKey<br>generateKey<br>sign<br>verify | ~importKey<br>exportKey<br>~generateKey<br>~~sign~~<br>verify | ~importKey<br>~exportKey<br>generateKey<br>~~sign~~<br>verify |
|
98 | | RS384 | importKey<br>exportKey<br>generateKey<br>sign<br>verify | importKey<br>exportKey<br>~~generateKey~~<br>sign<br>verify | importKey<br>exportKey<br>generateKey<br>sign<br>verify | importKey<br>~~exportKey~~<br>generateKey<br>sign<br>verify | ~importKey<br>exportKey<br>~generateKey<br>sign<br>verify | importKey<br>exportKey<br>generateKey<br>sign<br>verify |
|
99 | | RS512 | importKey<br>exportKey<br>generateKey<br>sign<br>verify | importKey<br>exportKey<br>~~generateKey~~<br>sign<br>verify | importKey<br>exportKey<br>generateKey<br>sign<br>verify | importKey<br>~~exportKey~~<br>generateKey<br>sign<br>verify | ~importKey<br>exportKey<br>~generateKey<br>sign<br>verify | importKey<br>exportKey<br>generateKey<br>~~sign~~<br>~~verify~~ |
|
100 | | PS256 | importKey<br>exportKey<br>generateKey<br>sign<br>verify | importKey<br>exportKey<br>~~generateKey~~<br>sign<br>verify | importKey<br>exportKey<br>generateKey<br>sign<br>verify | importKey<br>~~exportKey~~<br>generateKey<br>sign<br>verify | ? | ? |
|
101 | | PS384 | importKey<br>exportKey<br>generateKey<br>sign<br>verify | importKey<br>exportKey<br>~~generateKey~~<br>sign<br>verify | importKey<br>exportKey<br>generateKey<br>sign<br>verify | importKey<br>~~exportKey~~<br>generateKey<br>sign<br>verify | ? | ? |
|
102 | | PS512 | importKey<br>exportKey<br>generateKey<br>sign<br>verify | importKey<br>exportKey<br>~~generateKey~~<br>sign<br>verify | importKey<br>exportKey<br>generateKey<br>sign<br>verify | importKey<br>~~exportKey~~<br>generateKey<br>sign<br>verify | ? | ? |
|
103 | | ES256 | importKey<br>exportKey<br>generateKey<br>sign<br>verify | importKey<br>exportKey<br>generateKey<br>sign<br>verify | importKey<br>exportKey<br>generateKey<br>sign<br>verify | importKey<br>exportKey<br>generateKey<br>sign<br>verify | x | x |
|
104 | | ES384 | importKey<br>exportKey<br>generateKey<br>sign<br>verify | importKey<br>exportKey<br>generateKey<br>sign<br>verify | importKey<br>exportKey<br>generateKey<br>sign<br>verify | importKey<br>exportKey<br>generateKey<br>sign<br>verify | x | x |
|
105 | | ES512 | importKey<br>exportKey<br>generateKey<br>sign<br>verify | importKey<br>exportKey<br>generateKey<br>sign<br>verify | importKey<br>exportKey<br>generateKey<br>sign<br>verify | x | x | x |
|
106 | | RSA1_5 | ? | ? | ? | ? | ? | ? |
|
107 | | RSA-OAEP | ? | ? | ? | ? | ? | ? |
|
108 | | RSA-OAEP-256 | ? | ? | ? | ? | ? | ? |
|
109 | | A128KW | ? | ? | ? | ? | ? | ? |
|
110 | | A192KW | ? | ? | ? | ? | ? | ? |
|
111 | | A256KW | ? | ? | ? | ? | ? | ? |
|
112 | | dir | ? | ? | ? | ? | ? | ? |
|
113 | | ECDH-ES | ? | ? | ? | ? | ? | ? |
|
114 | | ECDH-ES+A128KW | ? | ? | ? | ? | ? | ? |
|
115 | | ECDH-ES+A192KW | ? | ? | ? | ? | ? | ? |
|
116 | | ECDH-ES+A256KW | ? | ? | ? | ? | ? | ? |
|
117 | | A128GCMKW | ? | ? | ? | ? | ? | ? |
|
118 | | A192GCMKW | ? | ? | ? | ? | ? | ? |
|
119 | | A256GCMKW | ? | ? | ? | ? | ? | ? |
|
120 | | PBES2-HS256+A128KW | ? | ? | ? | ? | ? | ? |
|
121 | | PBES2-HS384+A192KW | ? | ? | ? | ? | ? | ? |
|
122 | | PBES2-HS512+A256KW | ? | ? | ? | ? | ? | ? |
|
123 |
|
124 | Here's a legend for the [JWA alg abbreviations](https://tools.ietf.org/html/rfc7518#section-3.1):
|
125 |
|
126 | | Key | Signature, MAC or Key Management Algorithm |
|
127 | | ------------------ | ----------------------------------------------------------------------------- |
|
128 | | HS256 | HMAC using SHA-256 |
|
129 | | HS384 | HMAC using SHA-384 |
|
130 | | HS512 | HMAC using SHA-512 |
|
131 | | RS256 | RSASSA-PKCS1-v1_5 using SHA-256 |
|
132 | | RS384 | RSASSA-PKCS1-v1_5 using SHA-384 |
|
133 | | RS512 | RSASSA-PKCS1-v1_5 using SHA-512 |
|
134 | | ES256 | ECDSA using P-256 and SHA-256 |
|
135 | | ES384 | ECDSA using P-384 and SHA-384 |
|
136 | | ES512 | ECDSA using P-521 and SHA-512 |
|
137 | | PS256 | RSASSA-PSS using SHA-256 and MGF1 with SHA-256 |
|
138 | | PS384 | RSASSA-PSS using SHA-384 and MGF1 with SHA-384 |
|
139 | | PS512 | RSASSA-PSS using SHA-512 and MGF1 with SHA-512 |
|
140 | | RSA1_5 | RSAES-PKCS1-v1_5 |
|
141 | | RSA-OAEP | RSAES OAEP using default parameters |
|
142 | | RSA-OAEP-256 | RSAES OAEP using SHA-256 and MGF1 with SHA-256 |
|
143 | | A128KW | AES Key Wrap with default initial value using 128-bit key |
|
144 | | A192KW | AES Key Wrap with default initial value using 192-bit key |
|
145 | | A256KW | AES Key Wrap with default initial value using 256-bit key |
|
146 | | dir | Direct use of a shared symmetric key as the CEK |
|
147 | | ECDH-ES | Elliptic Curve Diffie-Hellman Ephemeral Static key agreement using Concat KDF |
|
148 | | ECDH-ES+A128KW | ECDH-ES using Concat KDF and CEK wrapped with "A128KW" |
|
149 | | ECDH-ES+A192KW | ECDH-ES using Concat KDF and CEK wrapped with "A192KW" |
|
150 | | ECDH-ES+A256KW | ECDH-ES using Concat KDF and CEK wrapped with "A256KW" |
|
151 | | A128GCMKW | Key wrapping with AES GCM using 128-bit key |
|
152 | | A192GCMKW | Key wrapping with AES GCM using 192-bit key |
|
153 | | A256GCMKW | Key wrapping with AES GCM using 256-bit key |
|
154 | | PBES2-HS256+A128KW | PBES2 with HMAC SHA-256 and "A128KW" wrapping |
|
155 | | PBES2-HS384+A192KW | PBES2 with HMAC SHA-384 and "A192KW" wrapping |
|
156 | | PBES2-HS512+A256KW | PBES2 with HMAC SHA-512 and "A256KW" wrapping |
|
157 |
|
158 | ## License
|
159 |
|
160 | MIT
|