Skip to content

Commit ee77823

Browse files
committed
feat support A128CBC-HS256 encryption algorithm for JWE
Signed-off-by: Timo Glastra <[email protected]>
1 parent 3a2b741 commit ee77823

File tree

3 files changed

+51
-12
lines changed

3 files changed

+51
-12
lines changed

packages/askar/src/wallet/AskarBaseWallet.ts

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -483,12 +483,13 @@ export abstract class AskarBaseWallet implements Wallet {
483483
data,
484484
header,
485485
}: WalletDirectEncryptCompactJwtEcdhEsOptions) {
486-
if (encryptionAlgorithm !== 'A256GCM') {
487-
throw new WalletError(`Encryption algorithm ${encryptionAlgorithm} is not supported. Only A256GCM is supported`)
486+
if (encryptionAlgorithm !== 'A256GCM' && encryptionAlgorithm !== 'A128CBC-HS256') {
487+
throw new WalletError(
488+
`Encryption algorithm ${encryptionAlgorithm} is not supported. Only A256GCM and A128CBC-HS256 are supported`
489+
)
488490
}
489491

490-
// Only one supported for now
491-
const encAlg = KeyAlgs.AesA256Gcm
492+
const encAlg = encryptionAlgorithm === 'A256GCM' ? KeyAlgs.AesA256Gcm : KeyAlgs.AesA128CbcHs256
492493

493494
// Create ephemeral key
494495
const ephemeralKey = AskarKey.generate(keyAlgFromString(recipientKey.keyType))
@@ -497,7 +498,7 @@ export abstract class AskarBaseWallet implements Wallet {
497498
...header,
498499
apv,
499500
apu,
500-
enc: 'A256GCM',
501+
enc: encryptionAlgorithm,
501502
alg: 'ECDH-ES',
502503
epk: ephemeralKey.jwkPublic,
503504
}
@@ -548,8 +549,8 @@ export abstract class AskarBaseWallet implements Wallet {
548549
if (header.alg !== 'ECDH-ES') {
549550
throw new WalletError('Only ECDH-ES alg value is supported')
550551
}
551-
if (header.enc !== 'A256GCM') {
552-
throw new WalletError('Only A256GCM enc value is supported')
552+
if (header.enc !== 'A256GCM' && header.enc !== 'A128CBC-HS256') {
553+
throw new WalletError('Only A256GCM and A128CBC-HS256 enc values are supported')
553554
}
554555
if (!header.epk || typeof header.epk !== 'object') {
555556
throw new WalletError('header epk value must contain a JWK')
@@ -566,9 +567,7 @@ export abstract class AskarBaseWallet implements Wallet {
566567
throw new WalletError('Key entry not found')
567568
}
568569

569-
// Only one supported for now
570-
const encAlg = KeyAlgs.AesA256Gcm
571-
570+
const encAlg = header.enc === 'A256GCM' ? KeyAlgs.AesA256Gcm : KeyAlgs.AesA128CbcHs256
572571
const ecdh = new EcdhEs({
573572
algId: Uint8Array.from(Buffer.from(header.enc)),
574573
apu: header.apu ? Uint8Array.from(TypedArrayEncoder.fromBase64(header.apu)) : Uint8Array.from([]),

packages/askar/src/wallet/__tests__/AskarWallet.test.ts

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,7 @@ describe('AskarWallet basic operations', () => {
176176
await expect(askarWallet.verify({ key: k256Key, data: message, signature })).resolves.toStrictEqual(true)
177177
})
178178

179-
test('Encrypt and decrypt using JWE ECDH-ES', async () => {
179+
test('Encrypt and decrypt using JWE ECDH-ES A256GCM', async () => {
180180
const recipientKey = await askarWallet.createKey({
181181
keyType: KeyType.P256,
182182
})
@@ -216,6 +216,46 @@ describe('AskarWallet basic operations', () => {
216216
expect(JsonEncoder.fromBuffer(data)).toEqual({ vp_token: ['something'] })
217217
})
218218

219+
test('Encrypt and decrypt using JWE ECDH-ES A128CBC-HS256', async () => {
220+
const recipientKey = await askarWallet.createKey({
221+
keyType: KeyType.P256,
222+
})
223+
224+
const apv = TypedArrayEncoder.toBase64URL(TypedArrayEncoder.fromString('nonce-from-auth-request'))
225+
const apu = TypedArrayEncoder.toBase64URL(TypedArrayEncoder.fromString(await askarWallet.generateNonce()))
226+
227+
const compactJwe = await askarWallet.directEncryptCompactJweEcdhEs({
228+
data: JsonEncoder.toBuffer({ vp_token: ['something'] }),
229+
apu,
230+
apv,
231+
encryptionAlgorithm: 'A128CBC-HS256',
232+
header: {
233+
kid: 'some-kid',
234+
},
235+
recipientKey,
236+
})
237+
238+
const { data, header } = await askarWallet.directDecryptCompactJweEcdhEs({
239+
compactJwe,
240+
recipientKey,
241+
})
242+
243+
expect(header).toEqual({
244+
kid: 'some-kid',
245+
apv,
246+
apu,
247+
enc: 'A128CBC-HS256',
248+
alg: 'ECDH-ES',
249+
epk: {
250+
kty: 'EC',
251+
crv: 'P-256',
252+
x: expect.any(String),
253+
y: expect.any(String),
254+
},
255+
})
256+
expect(JsonEncoder.fromBuffer(data)).toEqual({ vp_token: ['something'] })
257+
})
258+
219259
test('decrypt using JWE ECDH-ES based on test vector from OpenID Conformance test', async () => {
220260
const {
221261
compactJwe,

packages/core/src/wallet/Wallet.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@ export interface UnpackedMessageContext {
122122

123123
export interface WalletDirectEncryptCompactJwtEcdhEsOptions {
124124
recipientKey: Key
125-
encryptionAlgorithm: 'A256GCM'
125+
encryptionAlgorithm: 'A256GCM' | 'A128CBC-HS256'
126126
apu?: string
127127
apv?: string
128128
data: Buffer

0 commit comments

Comments
 (0)