deno.land / x / jose@v5.2.4 / runtime / encrypt.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
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
import { concat, uint64be } from '../lib/buffer_utils.ts'import type { EncryptFunction } from './interfaces.d.ts'import checkIvLength from '../lib/check_iv_length.ts'import checkCekLength from './check_cek_length.ts'import crypto, { isCryptoKey } from './webcrypto.ts'import { checkEncCryptoKey } from '../lib/crypto_key.ts'import invalidKeyInput from '../lib/invalid_key_input.ts'import generateIv from '../lib/iv.ts'import { JOSENotSupported } from '../util/errors.ts'import { types } from './is_key_like.ts'
async function cbcEncrypt( enc: string, plaintext: Uint8Array, cek: Uint8Array | CryptoKey, iv: Uint8Array, aad: Uint8Array,) { if (!(cek instanceof Uint8Array)) { throw new TypeError(invalidKeyInput(cek, 'Uint8Array')) } const keySize = parseInt(enc.slice(1, 4), 10) const encKey = await crypto.subtle.importKey( 'raw', cek.subarray(keySize >> 3), 'AES-CBC', false, ['encrypt'], ) const macKey = await crypto.subtle.importKey( 'raw', cek.subarray(0, keySize >> 3), { hash: `SHA-${keySize << 1}`, name: 'HMAC', }, false, ['sign'], )
const ciphertext = new Uint8Array( await crypto.subtle.encrypt( { iv, name: 'AES-CBC', }, encKey, plaintext, ), )
const macData = concat(aad, iv, ciphertext, uint64be(aad.length << 3)) const tag = new Uint8Array( (await crypto.subtle.sign('HMAC', macKey, macData)).slice(0, keySize >> 3), )
return { ciphertext, tag, iv }}
async function gcmEncrypt( enc: string, plaintext: Uint8Array, cek: Uint8Array | CryptoKey, iv: Uint8Array, aad: Uint8Array,) { let encKey: CryptoKey if (cek instanceof Uint8Array) { encKey = await crypto.subtle.importKey('raw', cek, 'AES-GCM', false, ['encrypt']) } else { checkEncCryptoKey(cek, enc, 'encrypt') encKey = cek }
const encrypted = new Uint8Array( await crypto.subtle.encrypt( { additionalData: aad, iv, name: 'AES-GCM', tagLength: 128, }, encKey, plaintext, ), )
const tag = encrypted.slice(-16) const ciphertext = encrypted.slice(0, -16)
return { ciphertext, tag, iv }}
const encrypt: EncryptFunction = async ( enc: string, plaintext: Uint8Array, cek: unknown, iv: Uint8Array | undefined, aad: Uint8Array,) => { if (!isCryptoKey(cek) && !(cek instanceof Uint8Array)) { throw new TypeError(invalidKeyInput(cek, ...types, 'Uint8Array')) }
if (iv) { checkIvLength(enc, iv) } else { iv = generateIv(enc) }
switch (enc) { case 'A128CBC-HS256': case 'A192CBC-HS384': case 'A256CBC-HS512': if (cek instanceof Uint8Array) { checkCekLength(cek, parseInt(enc.slice(-3), 10)) } return cbcEncrypt(enc, plaintext, cek, iv, aad) case 'A128GCM': case 'A192GCM': case 'A256GCM': if (cek instanceof Uint8Array) { checkCekLength(cek, parseInt(enc.slice(1, 4), 10)) } return gcmEncrypt(enc, plaintext, cek, iv, aad) default: throw new JOSENotSupported('Unsupported JWE Content Encryption Algorithm') }}
export default encrypt
jose

Version Info

Tagged at
a month ago