gdc-common-utils-ts 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (100) hide show
  1. package/PUBLISHING.md +33 -0
  2. package/__tests__/AesManager.test.ts +53 -0
  3. package/__tests__/CryptographyService.test.ts +194 -0
  4. package/__tests__/bundle.test.ts +29 -0
  5. package/__tests__/content.test.ts +72 -0
  6. package/__tests__/crypto-encode-decode.test.ts +52 -0
  7. package/__tests__/crypto-hmac.test.ts +21 -0
  8. package/__tests__/did-generateServiceId.errors.test.ts +8 -0
  9. package/__tests__/did-generateServiceId.test.ts +18 -0
  10. package/__tests__/models-clinical-sections.test.ts +32 -0
  11. package/__tests__/models-multibase58.test.ts +33 -0
  12. package/__tests__/multibase58.errors.test.ts +7 -0
  13. package/__tests__/multibase58.test.ts +28 -0
  14. package/__tests__/multibasehash.test.ts +25 -0
  15. package/__tests__/utils-actor.test.ts +22 -0
  16. package/__tests__/utils-base-convert.test.ts +57 -0
  17. package/__tests__/utils-baseN.test.ts +40 -0
  18. package/__tests__/utils-did-extra.test.ts +33 -0
  19. package/__tests__/utils-format-converter.test.ts +87 -0
  20. package/__tests__/utils-jwt.test.ts +57 -0
  21. package/__tests__/utils-manager-error.test.ts +11 -0
  22. package/__tests__/utils-normalize.test.ts +15 -0
  23. package/__tests__/utils-object-convert.test.ts +38 -0
  24. package/__tests__/utils-string-convert.test.ts +20 -0
  25. package/__tests__/utils-string-utils.test.ts +25 -0
  26. package/__tests__/utils-url.test.ts +21 -0
  27. package/babel.config.cjs +5 -0
  28. package/jest.config.ts +46 -0
  29. package/package.json +36 -0
  30. package/src/AesManager.ts +82 -0
  31. package/src/CryptographyService.ts +461 -0
  32. package/src/JweManager.ts.txt +365 -0
  33. package/src/KmsService.txt +493 -0
  34. package/src/constants/Schemas.ts +61 -0
  35. package/src/constants/index.ts +1 -0
  36. package/src/constants/schemaorg.ts +193 -0
  37. package/src/cryptoDecode.ts +104 -0
  38. package/src/cryptoEncode.ts +36 -0
  39. package/src/cryptography.abstract.ts +29 -0
  40. package/src/hmac.ts +15 -0
  41. package/src/index.ts +3 -0
  42. package/src/interfaces/Cryptography.types.ts +131 -0
  43. package/src/interfaces/ICryptoHelper.ts +33 -0
  44. package/src/interfaces/ICryptography.ts +177 -0
  45. package/src/interfaces/IWallet.ts +62 -0
  46. package/src/interfaces/MlDsa.ts +25 -0
  47. package/src/interfaces/MlKem.ts +18 -0
  48. package/src/models/aes.ts +93 -0
  49. package/src/models/auth.ts +38 -0
  50. package/src/models/bundle.ts +152 -0
  51. package/src/models/bundle.txt +93 -0
  52. package/src/models/clinical-sections.en.ts +82 -0
  53. package/src/models/clinical-sections.ts +64 -0
  54. package/src/models/comm.ts +63 -0
  55. package/src/models/confidential-job.ts +100 -0
  56. package/src/models/confidential-message.ts +137 -0
  57. package/src/models/confidential-storage.ts +170 -0
  58. package/src/models/consent-rule.ts +141 -0
  59. package/src/models/crypto.ts +43 -0
  60. package/src/models/device-license.ts +161 -0
  61. package/src/models/did.ts +81 -0
  62. package/src/models/index.ts +31 -0
  63. package/src/models/indexing.ts +20 -0
  64. package/src/models/issue.ts +85 -0
  65. package/src/models/jsonapi.ts +19 -0
  66. package/src/models/jwe.ts +132 -0
  67. package/src/models/jwk.ts +50 -0
  68. package/src/models/jws.ts +42 -0
  69. package/src/models/jwt.ts +15 -0
  70. package/src/models/multibase58.ts +46 -0
  71. package/src/models/oidc4ida.common.model.ts +39 -0
  72. package/src/models/oidc4ida.document.model.ts +61 -0
  73. package/src/models/oidc4ida.electronicRecord.model.ts +86 -0
  74. package/src/models/oidc4ida.evidence.model.ts +69 -0
  75. package/src/models/openid-device.ts +146 -0
  76. package/src/models/operation-outcome.ts +34 -0
  77. package/src/models/params.ts +142 -0
  78. package/src/models/resource-document.ts +21 -0
  79. package/src/models/response.ts +5 -0
  80. package/src/models/urlPath.ts +76 -0
  81. package/src/models/verifiable-credential.ts +52 -0
  82. package/src/types/noble-hashes.d.ts +4 -0
  83. package/src/utils/actor.ts +52 -0
  84. package/src/utils/base-convert.ts +77 -0
  85. package/src/utils/baseN.ts +203 -0
  86. package/src/utils/bundle.ts +30 -0
  87. package/src/utils/content.ts +66 -0
  88. package/src/utils/did.ts +155 -0
  89. package/src/utils/format-converter.ts +119 -0
  90. package/src/utils/index.ts +13 -0
  91. package/src/utils/jwt.ts +165 -0
  92. package/src/utils/manager-error.ts +27 -0
  93. package/src/utils/multibase58.ts +46 -0
  94. package/src/utils/multibasehash.ts +28 -0
  95. package/src/utils/normalize.ts +43 -0
  96. package/src/utils/object-convert.ts +57 -0
  97. package/src/utils/string-convert.ts +71 -0
  98. package/src/utils/string-utils.ts +70 -0
  99. package/src/utils/url.ts +46 -0
  100. package/tsconfig.json +13 -0
@@ -0,0 +1,365 @@
1
+ // IMPORTANT! Install first 'react-native-randombytes' in react-native
2
+
3
+ /* Copyright (c) Conéctate Soluciones y Aplicaciones SL, Copyright (c) Connecting Solution & Applications Ltd. */
4
+ /* Apache License 2.0 */
5
+
6
+ // import sjcl from 'sjclplus';
7
+ import { AES_GCM_JWA_ENC } from '@/models/aes';
8
+ import { RecipientDataJWE, ProtectedHeadersJWE, UnprotectedHeadersJWE } from '@/models/jwe';
9
+ import pako from 'pako';
10
+ import { JWEData } from './interfaces/Cryptography.types';
11
+ // import { createRandomBytesAsBitArray } from '../crypto/security.manager';
12
+
13
+ export const EncAlgoritmAES256GCM = 'aes-256-gcm';
14
+
15
+ const initVectorSize = 16;
16
+
17
+ export class JWEManager {
18
+ constructor(){}
19
+
20
+ /** It gets the recipient data by kid (JWK thumbprint), decrypts the CEK and then the message.
21
+ * The decrypted message can be both simple string or JSON.
22
+ */
23
+ /*
24
+ async decryptByPrivateKyberKeyBytes(privateKeyBytes:Uint8Array, kid:string, jweData:StandardJWE, typ?:string): Promise<UnencryptedJWE> {
25
+ return await decryptDataRecipient(privateKeyBytes, kid, jweData, typ);
26
+ }
27
+ */
28
+
29
+ /** It returns empty string "" if some error or a concatenated string as per RFC7516 specification for only one recipient */
30
+ public static compactDataJWE(jweData: JWEData | undefined): string {
31
+ return compactDataJWE(jweData)
32
+ }
33
+
34
+ /** It returns empty string "" if some error or a concatenated string as per RFC7516 specification for only one recipient */
35
+ public static async createCompactJWE(
36
+ cekBase64Url: string,
37
+ payloadData: object,
38
+ recipient: RecipientDataJWE,
39
+ protectHdersDecoded: ProtectedHeadersJWE,
40
+ unprotectedHders?: UnprotectedHeadersJWE | undefined,
41
+ ): Promise<string> {
42
+ return await createCompactJWE(cekBase64Url, payloadData, recipient, protectHdersDecoded, unprotectedHders)
43
+ }
44
+
45
+ /** Create "ciphertext", "tag", "iv" (initialization vector, a nonce), "protected" (headers) and optional "unprotected" (headers)
46
+ * but not "recipients" (it will be created by a parent function).
47
+ * @param cekBase64Url symmetric key for the data AES encryption.
48
+ * @param plaintextDataStringified stringified payload in case of a JWT.
49
+ * @param aadBase64Url the JWE `recipients` encoded in Base64Url when using the JWE JSON Serialization (multiple recipients/participants).
50
+ * @param ivBytesLength usually 12 bytes (96 bits) but NIST 800-38D 8.2.2 (RGB Construction of IV) allows to be 16 bytes (128 bits)
51
+ */
52
+ public static async encryptDataJWE (
53
+ cekBase64Url: string, // symmetric key for the data AES encryption.
54
+ plaintextDataStringified: string, // stringified payload in case of a JWT.
55
+ aadBase64Url: string, // the JWE `recipients` encoded in Base64Url when using the JWE JSON Serialization (multiple recipients/participants).
56
+ ivBytesLength? :number // usually 12 bytes (96 bits) but NIST 800-38D 8.2.2 (RGB Construction of IV) allows to be 16 bytes (128 bits)
57
+ ): Promise<JWEData>
58
+ {
59
+ return encryptDataJWE(cekBase64Url, plaintextDataStringified, aadBase64Url, ivBytesLength)
60
+ }
61
+ }
62
+
63
+ /** TODO: creates a compact JWE only for one recipient as per the OpenID specification
64
+ * It returns empty string "" if some error or a concatenated string as per RFC7516 specification for only one recipient
65
+ * It sets protectHeadersDecoded.enc = "A256GCM" and
66
+ * AAD = ASCII(Base64Url(protectHeadersDecoded)) as per https://www.rfc-editor.org/rfc/rfc7516#section-5.1
67
+ */
68
+ export async function createCompactJWE(
69
+ cekBase64Url: string,
70
+ payloadData: object,
71
+ recipient: RecipientDataJWE,
72
+ protectHdersDecoded: ProtectedHeadersJWE,
73
+ unprotectedHders?: UnprotectedHeadersJWE | undefined,
74
+ ): Promise<string> {
75
+ const jweData = await createDataJWE(cekBase64Url, JSON.stringify(payloadData), protectHdersDecoded);
76
+ // TODO: encrypt the cek for the recipient and set the recipient data in the JWE data
77
+ return compactDataJWE(jweData)
78
+ }
79
+
80
+ /** Returns standard JWE in JSON format (one or more recipients) or undefined, but not compacted for a sole recipient
81
+ * It sets protectHeadersDecoded.enc = "A256GCM" and
82
+ * AAD = ASCII(Base64Url(protectHeadersDecoded)) as per https://www.rfc-editor.org/rfc/rfc7516#section-5.1
83
+ */
84
+ export async function createDataJWE(
85
+ cekBase64Url: string,
86
+ plaintextData: string,
87
+ protectHeadersDecoded: ProtectedHeadersJWE,
88
+ ): Promise<StandardJWE | undefined> {
89
+ // TODO: check the length of the CEK is 32 bytes
90
+
91
+ // 11. If a "zip" parameter was included, compress the plaintext using the specified compression algorithm
92
+ // and let M be the octet sequence representing the compressed plaintext;
93
+ // otherwise, let M be the octet sequence representing the plaintext.
94
+ let payloadBytes;
95
+ try {
96
+ payloadBytes = stringToUint8Array(plaintextData);
97
+ if (protectHeadersDecoded.zip && protectHeadersDecoded.zip === 'DEF') {
98
+ payloadBytes = pako.deflate(payloadBytes); // compress (deflate) the payload data bytes
99
+ }
100
+ } catch (e) {
101
+ console.error(e);
102
+ return undefined
103
+ }
104
+
105
+ // the plaintext represents the unencrypted payload's data bytes (compressed or not)
106
+ const plaintextDataStringified = bytesArrayToString(payloadBytes);
107
+
108
+ // 12. Create the JSON object(s) containing the desired set of Header Parameters, which together comprise the JOSE Header:
109
+ // one or more of the JWE Protected Header, the JWE Shared Unprotected Header, and the JWE Per-Recipient Unprotected Header.
110
+
111
+ // TODO: check protected header claim "enc" is "A256GCM"
112
+
113
+ // 13. Compute the Encoded Protected Header value BASE64URL(UTF8(JWE Protected Header))
114
+ protectHeadersDecoded.enc = AES_GCM_JWA_ENC; // A256GCM
115
+ const protectedHderB64UrlSafe = objectToRawBase64UrlSafe(protectHeadersDecoded);
116
+
117
+ // 14. Let the Additional Authenticated Data encryption parameter be ASCII(Encoded Protected Header)
118
+ // as per https://www.rfc-editor.org/rfc/rfc7516#section-5.1
119
+ const aadBase64Url = protectedHderB64UrlSafe
120
+
121
+ // NIST 800-38D 8.2.2 (RGB Construction of IV) allows 128 bits to be randomly generated.
122
+ const initVectorBytesLength: number = 16;
123
+
124
+ // encrypt data
125
+ // TODO: if recipients===1 do compact serialiation, if recipients>1 do JSON serialization
126
+ let jweData = await encryptData(cekBase64Url, plaintextDataStringified, aadBase64Url)
127
+ // jweData.protected = protectedHderB64UrlSafe;
128
+
129
+ const standardJWE: StandardJWE = {
130
+ protected: protectedHderB64UrlSafe, // jweData.protected,
131
+ unprotected: jweData.unprotected,
132
+ recipients: jweData.recipients as RecipientDataJWE[],
133
+ iv: jweData.iv,
134
+ ciphertext: jweData.ciphertext,
135
+ tag: jweData.tag
136
+ }
137
+ return standardJWE // getCompactJWE(jweData)
138
+ }
139
+
140
+ /** It returns JWEData but recipients shall be created by the parent function.
141
+ * cekBase64Url: symmetric key for the data AES encryption.
142
+ * plaintextDataStringified: stringified payload in case of a JWT.
143
+ * aadBase64Url: the JWE `recipients` encoded in Base64Url when using the JWE JSON Serialization (multiple recipients/participants).
144
+ * ivBytesLength: usually 12 bytes (96 bits) but NIST 800-38D 8.2.2 (RGB Construction of IV) allows to be 16 bytes (128 bits)
145
+ * Note: scjl expects a UTF-8 data string (the "plaintext") instead of the data bytes
146
+ */
147
+ async function encryptData (
148
+ cekBase64Url: string, // symmetric key for the data AES encryption.
149
+ plaintextData: string, // stringified payload in case of a JWT.
150
+ aadBase64Url: string, // the JWE `recipients` encoded in Base64Url when using the JWE JSON Serialization (multiple recipients/participants).
151
+ ivBytesLength? :number // usually 12 bytes (96 bits) but NIST 800-38D 8.2.2 (RGB Construction of IV) allows to be 16 bytes (128 bits)
152
+ ): Promise<JWEData>
153
+ {
154
+ // Creating the random data: the "iv" and encrypting
155
+ // const nonceBitArray = createRandomBytesAsBitArray(ivBytesLength); // NIST 800.D allows 16 bytes length instead of the default 12 bytes
156
+ const nonceBase64Url = await generateRandomBytesBase64UrlEncoded(ivBytesLength || 16) // NIST 800-38D 8.2.2 (RGB Construction of IV) allows to be 16 bytes (128 bits) sjcl.codec.base64url.fromBits(nonceBitArray);
157
+ const ctAndTagBase64Url = await AESManager.encryptAESGCM(cekBase64Url, plaintextData, aadBase64Url, nonceBase64Url);
158
+
159
+ // Separate ciptertext/tag combination
160
+ return await AESManager.getProtectedDataForJWE(nonceBase64Url, ctAndTagBase64Url) as JWEData;
161
+ }
162
+
163
+ /** Create "ciphertext", "tag", "iv" (initialization vector, a nonce), "protected" (headers) and optional "unprotected" (headers)
164
+ * but not "recipients" (it will be created by a parent function).
165
+ * In the JWE JSON Serialization, a JWE is represented as a JSON object containing some or all of these eight members:
166
+ * - "protected", with the value BASE64URL(UTF8(JWE Protected Header))
167
+ * - "unprotected", with the value JWE Shared Unprotected Header
168
+ * - "recipients", array of JSON objects where each object contains information specific to a single recipient, but all all Header Parameter values are shared between all recipients.
169
+ * - "iv" is the value BASE64URL(JWE Initialization Vector)
170
+ * - "ciphertext" is the value BASE64URL(JWE Ciphertext)
171
+ * - "tag" is the value BASE64URL(JWE Authentication Tag)
172
+ * - "aad" is the DOUBLE Base64Url encoding value of the JWE Protected Headers: BASE64URL(JWE AAD) = BASE64URL( ASCII(BASE64URL(UTF8(JWE Protected Header))) )
173
+ * (see the AAD example at https://www.rfc-editor.org/rfc/rfc7516#section-3.3)
174
+ * @param cekBase64Url symmetric key for the data AES encryption.
175
+ * @param plaintextDataStringified stringified payload in case of a JWT.
176
+ * @param aadBase64Url the Additional Authenticated Data encryption parameter (AAD) protects the integrity of the JWE Protected Header (double Base64Url encoded as per the specification).
177
+ * @param ivBytesLength usually 12 bytes (96 bits) but NIST 800-38D 8.2.2 (RGB Construction of IV) allows to be 16 bytes (128 bits)
178
+ */
179
+ export async function encryptDataJWE (
180
+ cekBase64Url: string, // symmetric key for the data AES encryption.
181
+ plaintextDataStringified: string, // stringified payload in case of a JWT.
182
+ aadBase64Url: string, // NOTE: double Base64Url encoding: BASE64URL(JWE AAD) = BASE64URL( ASCII(BASE64URL(UTF8(JWE Protected Header))) )
183
+ ivBytesLength? :number // usually 12 bytes (96 bits) but NIST 800-38D 8.2.2 (RGB Construction of IV) allows to be 16 bytes (128 bits)
184
+ ): Promise<JWEData>
185
+ {
186
+ if (!ivBytesLength) ivBytesLength = 16; // NIST 800-38D 8.2.2 (RGB Construction of IV) allows to be 16 bytes (128 bits)
187
+ return encryptData(cekBase64Url, plaintextDataStringified, aadBase64Url, ivBytesLength)
188
+ }
189
+
190
+ /** It returns the JWE's plaintext decrypted data but not a JSON object */
191
+ export async function decryptDataJWE(cekBase64Url: string, jweData: JWEData): Promise<string> {
192
+ const plaintextData = await AESManager.decryptProtectedDataJWE(
193
+ cekBase64Url,
194
+ jweData.ciphertext as string,
195
+ jweData.protected, // protected headers (for the AES "AAD")
196
+ jweData.iv as string,
197
+ jweData.tag as string
198
+ );
199
+
200
+ return plaintextData; // it can be a JSON strified string
201
+ }
202
+
203
+ /** The Compact Serialization of this result is an empty string "" if some error or the concatenation string
204
+ * BASE64URL(UTF8(JWE Protected Header)) || '.' ||
205
+ * BASE64URL(JWE Encrypted Key) || '.' ||
206
+ * BASE64URL(JWE Initialization Vector) || '.' ||
207
+ * BASE64URL(JWE Ciphertext) || '.' ||
208
+ * BASE64URL(JWE Authentication Tag).
209
+ */
210
+ export function compactDataJWE(jweData: any | undefined): string {
211
+ if (!jweData || !jweData.recipients || !jweData.recipients.length || jweData.recipients.length<1
212
+ || !jweData.protected || !jweData.iv || !jweData.ciphertext || !jweData.tag ) {
213
+ return ""
214
+ } else {
215
+ return jweData.protected as string + "." +
216
+ jweData.recipients[0].encrypted_key as string + "." +
217
+ jweData.iv + "." + jweData.ciphertext + "." + jweData.tag
218
+ }
219
+ }
220
+
221
+ /** Gets recipient data by recipient's keyID (kid) */
222
+ export function getRecipientDataByKeyID(recipientsList: RecipientDataJWE[], kid: string): RecipientDataJWE | undefined{
223
+ let result;
224
+ if (recipientsList && recipientsList.length && recipientsList.length > 0) {
225
+ const recipientFound = recipientsList.some(
226
+ (recipient: RecipientDataJWE) => {
227
+ if (recipient.header && recipient.header.kid && recipient.header.kid === kid) {
228
+ result = recipient;
229
+ return true;
230
+ }
231
+ }
232
+ );
233
+ }
234
+ return result;
235
+ }
236
+
237
+ /** It gets the recipient data by kid (JWK thumbprint), decrypts the CEK and then the message.
238
+ * The decrypted message can be both simple string or JSON.
239
+ */
240
+ /*
241
+ export async function decryptDataRecipient(privateKeyBytes:Uint8Array, kid:string, jweData:StandardJWE, typ?:string): Promise<UnencryptedJWE> {
242
+ if (!privateKeyBytes || !kid) {
243
+ throw new Error(`the recipient's private key (bytes) and the public 'kid' (public keyID by thumbprint) are required`);
244
+ }
245
+
246
+ // getting the recipient data by kid
247
+ if (!jweData || !jweData.recipients || !jweData.recipients.length || jweData.recipients.length<1){
248
+ throw new Error('no recipients found');
249
+ }
250
+ let kidRecipient = {} as RecipientDataJWE;
251
+ const recipientFound = jweData.recipients.some(
252
+ (recipient: RecipientDataJWE) => {
253
+ if (recipient.header && recipient.header.kid && recipient.header.kid === kid) {
254
+ kidRecipient = recipient;
255
+ return true;
256
+ }
257
+ }
258
+ );
259
+ if (!recipientFound){
260
+ throw new Error('recipient kid not found');
261
+ }
262
+ if (!kidRecipient.encrypted_key){
263
+ throw new Error(`missing key for recipient kid ${kid}`);
264
+ }
265
+
266
+ // decrypt or decapsulate the CEK by the UHC supported algorithm used for the recipient (Kyber-768 or X25519)
267
+ if (!kidRecipient.header.alg){
268
+ throw new Error(`missing key for recipient kid ${kid}`);
269
+ }
270
+
271
+ const encapsulatedSymmetricKeyBytes: Uint8Array = ContentUtils.base64ToBytes(kidRecipient.encrypted_key);
272
+ let cekBytes: Uint8Array;
273
+ switch(kidRecipient.header.alg) {
274
+ case('Kyber-768'): {
275
+ cekBytes = await decapsulateBy768(encapsulatedSymmetricKeyBytes, privateKeyBytes);
276
+ break;
277
+ }
278
+ case('X25519'): {
279
+ throw new Error ('algoritim X25519 not implemented');
280
+ }
281
+ default: {
282
+ throw new Error (`algorithm "${kidRecipient.header.alg}" not supported`);
283
+ }
284
+ }
285
+
286
+ const cekBase64Url = bytesToRawBase64UrlSafe(cekBytes)
287
+
288
+ // checking AES 'A256GCM' encryption ('enc') header and 'typ' header
289
+ const jweProtectedDataJSON = ContentUtils.base64ToObject(jweData.protected) as ProtectedHeadersJWE;
290
+ if (!jweProtectedDataJSON || !jweProtectedDataJSON.enc || jweProtectedDataJSON.enc !== 'A256GCM') {
291
+ throw new Error('invalid AES GCM encryption header');
292
+ }
293
+ if (typ) {
294
+ console.log('content protected header "typ" = ', jweProtectedDataJSON.typ);
295
+ if (!jweProtectedDataJSON.typ || jweProtectedDataJSON.typ !== typ) {
296
+ throw new Error(`content header typ "${typ}" not found`);
297
+ }
298
+ }
299
+
300
+ let decryptedData = decryptDataJWE(cekBase64Url, jweData);
301
+
302
+ // creating the output
303
+ const unencryptedJWE: UnencryptedJWE = {
304
+ protectHdersDecoded: ContentUtils.base64ToObject(jweData.protected) as ProtectedHeadersJWE,
305
+ // recipient: kidRecipient, // it is not available in the unencrypted data
306
+ plaintext: decryptedData,
307
+ recipients: []
308
+ };
309
+ if (jweData.unprotected) {
310
+ unencryptedJWE.unprotected = jweData.unprotected;
311
+ }
312
+
313
+ return unencryptedJWE;
314
+ }
315
+ */
316
+
317
+ /*
318
+ export function jsonMessageByJWE(jwe: StandardJWE, privateKeyBytes: Uint8Array): object {
319
+ var dcipher = createDecipheriv(algorithm, privateKeyBytes, iv);
320
+ dcipher.setAAD(Buffer.from(toASCII(jweTokenParts[0])));
321
+ dcipher.setAuthTag(Buffer.from(chipherTextAuthTagHex, 'base64'));
322
+ var planText = dcipher.update(chipperTextHex, 'base64', 'utf8');
323
+ planText += dcipher.final('utf8');
324
+ console.log(planText);
325
+ }
326
+ */
327
+
328
+
329
+ /** It gets the recipient data by kid (JWK thumbprint), decrypts the CEK and then the message.
330
+ * The decrypted message can be both simple string or JSON.
331
+ */
332
+ /*
333
+ export async function cekDecryptBytes(jsonJWE:StandardJWE, privateKeyBytes:Uint8Array, kid:string, typ?:string): Promise<Uint8Array> {
334
+ if (!privateKeyBytes || !kid) {
335
+ throw new Error(`the recipient's private key (bytes) and the public 'kid' (public keyID by thumbprint) are required`);
336
+ }
337
+
338
+ // getting the recipient data by kid
339
+ if (!jsonJWE || !jsonJWE.recipients || !jsonJWE.recipients.length || jsonJWE.recipients.length<1){
340
+ throw new Error('no recipients found');
341
+ }
342
+ let kidRecipient = {} as RecipientDataJWE;
343
+ const recipientFound = jsonJWE.recipients.some(
344
+ (recipient: RecipientDataJWE) => {
345
+ if (recipient.header && recipient.header.kid && recipient.header.kid === kid) {
346
+ kidRecipient = recipient;
347
+ return true;
348
+ }
349
+ }
350
+ );
351
+ if (!recipientFound){
352
+ throw new Error('recipient kid not found');
353
+ }
354
+ if (!kidRecipient.encrypted_key){
355
+ throw new Error(`missing key for recipient kid ${kid}`);
356
+ }
357
+
358
+ // decrypt or decapsulate the CEK by the UHC supported algorithm used for the recipient (Kyber-768 or X25519)
359
+ if (!kidRecipient.header.alg){
360
+ throw new Error(`missing key for recipient kid ${kid}`);
361
+ }
362
+
363
+ const encapsulatedSymmetricKeyBytes: Uint8Array = base64OrUrlSafeToBytes(kidRecipient.encrypted_key);
364
+ }
365
+ */