-
Notifications
You must be signed in to change notification settings - Fork 1
/
index.ts
99 lines (89 loc) · 2.46 KB
/
index.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
import crypto from 'isomorphic-webcrypto'
import * as algos from 'jose-algorithms'
/**
* Generate a jwk or key pair
* @param {object} json
* @param {string} alg
* @param {object=} options
*/
export function generateKey(alg, {
modulusLength = 2048,
publicExponent = new Uint8Array([0x01, 0x00, 0x01]), // 65537
usages = ['sign', 'verify'],
extractable = true
} = {}) {
if (!algos[alg]) throw new Error(`alg must be one of ${Object.keys(algos)}`)
const algo = Object.assign({}, algos[alg])
if (algo.name === 'RSASSA-PKCS1-v1_5' || algo.name === 'RSA-PSS') {
algo.modulusLength = modulusLength
algo.publicExponent = publicExponent
}
if (algo.name === 'ECDSA') {
delete algo.hash
}
return crypto.subtle.generateKey(
algo,
extractable,
usages
)
.then(keys => {
if (!keys.publicKey) {
return { sharedKey: keys }
}
return keys
})
.catch(e => {
throw new Error(`couldn't generate key: ${e.message}`)
})
}
/**
* Import a jwk from a JSON object
* @param {object} json
* @param {object=} options
* @param {string} [options.alg=null] Defaults to alg in json
* @param {boolean} [options.extractable=false]
* @param {string[]} [options.usages=null] Defaults to key_ops in json
*/
export function importKey(json, {
alg = null,
extractable = true,
usages = null
} = {}) {
if (!json) throw new Error('jwk must be an object')
alg = alg || json.alg;
if (!algos[alg]) throw new Error(`alg must be one of ${Object.keys(algos)}`)
let algo = Object.assign({}, algos[alg])
if (json.kty === 'EC') {
algo.namedCurve = json.crv
delete algo.hash
}
// IE11 fix (should be added to webcrypto-shim)
// https://connect.microsoft.com/IE/feedback/details/2242108/webcryptoapi-importing-jwk-with-use-field-fails
if (typeof window !== 'undefined' && window.msCrypto) {
json = Object.assign({}, json)
delete json.use
}
// The node polyfill doesn't work without key_ops, although key_ops is optional
// https://tools.ietf.org/html/rfc7517#section-4.3
if (!json.key_ops) {
json = Object.assign({}, json)
json.key_ops = json.d ? ['sign'] : ['verify']
}
return crypto.subtle.importKey(
'jwk', // format
json,
algo,
extractable,
usages || json.key_ops
)
.catch(e => {
throw new Error(`couldn't import key: ${e.message}`)
})
}
/**
* Export a jwk as a JSON object
* @param key
*/
export function exportKey(key) {
return crypto.subtle.exportKey('jwk', key);
}