@lindorm/aes 0.6.5 → 0.7.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 (264) hide show
  1. package/README.md +126 -231
  2. package/dist/classes/AesKit.d.ts +4 -4
  3. package/dist/classes/AesKit.d.ts.map +1 -1
  4. package/dist/classes/AesKit.js +29 -33
  5. package/dist/classes/AesKit.js.map +1 -1
  6. package/dist/classes/index.d.ts +1 -1
  7. package/dist/classes/index.d.ts.map +1 -1
  8. package/dist/classes/index.js +1 -17
  9. package/dist/classes/index.js.map +1 -1
  10. package/dist/errors/AesError.js +2 -6
  11. package/dist/errors/AesError.js.map +1 -1
  12. package/dist/errors/index.d.ts +1 -1
  13. package/dist/errors/index.d.ts.map +1 -1
  14. package/dist/errors/index.js +1 -17
  15. package/dist/errors/index.js.map +1 -1
  16. package/dist/index.d.ts +5 -6
  17. package/dist/index.d.ts.map +1 -1
  18. package/dist/index.js +5 -22
  19. package/dist/index.js.map +1 -1
  20. package/dist/interfaces/AesKit.d.ts +3 -3
  21. package/dist/interfaces/AesKit.d.ts.map +1 -1
  22. package/dist/interfaces/AesKit.js +1 -2
  23. package/dist/interfaces/index.d.ts +1 -1
  24. package/dist/interfaces/index.d.ts.map +1 -1
  25. package/dist/interfaces/index.js +1 -17
  26. package/dist/interfaces/index.js.map +1 -1
  27. package/dist/internal/constants/version.js +3 -6
  28. package/dist/internal/constants/version.js.map +1 -1
  29. package/dist/internal/types/aes-data.d.ts +4 -4
  30. package/dist/internal/types/aes-data.d.ts.map +1 -1
  31. package/dist/internal/types/aes-data.js +1 -2
  32. package/dist/internal/types/aes-key-derivation.js +1 -2
  33. package/dist/internal/types/auth-tag.d.ts +2 -2
  34. package/dist/internal/types/auth-tag.d.ts.map +1 -1
  35. package/dist/internal/types/auth-tag.js +1 -2
  36. package/dist/internal/types/auth-tag.js.map +1 -1
  37. package/dist/internal/types/content-encryption-key.d.ts +2 -2
  38. package/dist/internal/types/content-encryption-key.d.ts.map +1 -1
  39. package/dist/internal/types/content-encryption-key.js +1 -2
  40. package/dist/internal/types/key-wrap.d.ts +1 -1
  41. package/dist/internal/types/key-wrap.d.ts.map +1 -1
  42. package/dist/internal/types/key-wrap.js +1 -2
  43. package/dist/internal/types/prepared-encryption.d.ts +3 -3
  44. package/dist/internal/types/prepared-encryption.d.ts.map +1 -1
  45. package/dist/internal/types/prepared-encryption.js +1 -2
  46. package/dist/internal/utils/aes-header.d.ts +3 -3
  47. package/dist/internal/utils/aes-header.d.ts.map +1 -1
  48. package/dist/internal/utils/aes-header.js +22 -30
  49. package/dist/internal/utils/aes-header.js.map +1 -1
  50. package/dist/internal/utils/calculate/calculate-aes-encryption.d.ts +2 -2
  51. package/dist/internal/utils/calculate/calculate-aes-encryption.d.ts.map +1 -1
  52. package/dist/internal/utils/calculate/calculate-aes-encryption.js +4 -8
  53. package/dist/internal/utils/calculate/calculate-aes-encryption.js.map +1 -1
  54. package/dist/internal/utils/calculate/calculate-content-encryption-key-size.d.ts +2 -2
  55. package/dist/internal/utils/calculate/calculate-content-encryption-key-size.d.ts.map +1 -1
  56. package/dist/internal/utils/calculate/calculate-content-encryption-key-size.js +4 -8
  57. package/dist/internal/utils/calculate/calculate-content-encryption-key-size.js.map +1 -1
  58. package/dist/internal/utils/calculate/calculate-key-wrap-encryption.d.ts +1 -1
  59. package/dist/internal/utils/calculate/calculate-key-wrap-encryption.d.ts.map +1 -1
  60. package/dist/internal/utils/calculate/calculate-key-wrap-encryption.js +3 -7
  61. package/dist/internal/utils/calculate/calculate-key-wrap-encryption.js.map +1 -1
  62. package/dist/internal/utils/calculate/calculate-key-wrap-size.d.ts +2 -2
  63. package/dist/internal/utils/calculate/calculate-key-wrap-size.d.ts.map +1 -1
  64. package/dist/internal/utils/calculate/calculate-key-wrap-size.js +3 -7
  65. package/dist/internal/utils/calculate/calculate-key-wrap-size.js.map +1 -1
  66. package/dist/internal/utils/calculate/calculate-pbkdf-hash.d.ts +2 -2
  67. package/dist/internal/utils/calculate/calculate-pbkdf-hash.d.ts.map +1 -1
  68. package/dist/internal/utils/calculate/calculate-pbkdf-hash.js +3 -7
  69. package/dist/internal/utils/calculate/calculate-pbkdf-hash.js.map +1 -1
  70. package/dist/internal/utils/calculate/calculate-rsa-oaep-hash.d.ts +2 -2
  71. package/dist/internal/utils/calculate/calculate-rsa-oaep-hash.d.ts.map +1 -1
  72. package/dist/internal/utils/calculate/calculate-rsa-oaep-hash.js +3 -7
  73. package/dist/internal/utils/calculate/calculate-rsa-oaep-hash.js.map +1 -1
  74. package/dist/internal/utils/content.d.ts +1 -1
  75. package/dist/internal/utils/content.d.ts.map +1 -1
  76. package/dist/internal/utils/content.js +11 -17
  77. package/dist/internal/utils/content.js.map +1 -1
  78. package/dist/internal/utils/data/auth-tag-hmac.d.ts +1 -1
  79. package/dist/internal/utils/data/auth-tag-hmac.d.ts.map +1 -1
  80. package/dist/internal/utils/data/auth-tag-hmac.js +9 -14
  81. package/dist/internal/utils/data/auth-tag-hmac.js.map +1 -1
  82. package/dist/internal/utils/data/auth-tag.d.ts +1 -1
  83. package/dist/internal/utils/data/auth-tag.d.ts.map +1 -1
  84. package/dist/internal/utils/data/auth-tag.js +9 -14
  85. package/dist/internal/utils/data/auth-tag.js.map +1 -1
  86. package/dist/internal/utils/data/get-initialisation-vector.d.ts +1 -1
  87. package/dist/internal/utils/data/get-initialisation-vector.d.ts.map +1 -1
  88. package/dist/internal/utils/data/get-initialisation-vector.js +6 -10
  89. package/dist/internal/utils/data/get-initialisation-vector.js.map +1 -1
  90. package/dist/internal/utils/data/split-content-encryption-key.d.ts +1 -1
  91. package/dist/internal/utils/data/split-content-encryption-key.d.ts.map +1 -1
  92. package/dist/internal/utils/data/split-content-encryption-key.js +4 -8
  93. package/dist/internal/utils/data/split-content-encryption-key.js.map +1 -1
  94. package/dist/internal/utils/diffie-hellman/diffie-hellman-key-wrap.d.ts +1 -1
  95. package/dist/internal/utils/diffie-hellman/diffie-hellman-key-wrap.d.ts.map +1 -1
  96. package/dist/internal/utils/diffie-hellman/diffie-hellman-key-wrap.js +20 -25
  97. package/dist/internal/utils/diffie-hellman/diffie-hellman-key-wrap.js.map +1 -1
  98. package/dist/internal/utils/diffie-hellman/diffie-hellman.d.ts +1 -1
  99. package/dist/internal/utils/diffie-hellman/diffie-hellman.d.ts.map +1 -1
  100. package/dist/internal/utils/diffie-hellman/diffie-hellman.js +16 -21
  101. package/dist/internal/utils/diffie-hellman/diffie-hellman.js.map +1 -1
  102. package/dist/internal/utils/diffie-hellman/shared-secret.d.ts +3 -3
  103. package/dist/internal/utils/diffie-hellman/shared-secret.d.ts.map +1 -1
  104. package/dist/internal/utils/diffie-hellman/shared-secret.js +22 -27
  105. package/dist/internal/utils/diffie-hellman/shared-secret.js.map +1 -1
  106. package/dist/internal/utils/encoded-aes.d.ts +2 -2
  107. package/dist/internal/utils/encoded-aes.d.ts.map +1 -1
  108. package/dist/internal/utils/encoded-aes.js +18 -23
  109. package/dist/internal/utils/encoded-aes.js.map +1 -1
  110. package/dist/internal/utils/encrypt-content.d.ts +1 -1
  111. package/dist/internal/utils/encrypt-content.d.ts.map +1 -1
  112. package/dist/internal/utils/encrypt-content.js +14 -18
  113. package/dist/internal/utils/encrypt-content.js.map +1 -1
  114. package/dist/internal/utils/encrypt-encoded.d.ts +2 -2
  115. package/dist/internal/utils/encrypt-encoded.d.ts.map +1 -1
  116. package/dist/internal/utils/encrypt-encoded.js +15 -19
  117. package/dist/internal/utils/encrypt-encoded.js.map +1 -1
  118. package/dist/internal/utils/encrypt-serialised.d.ts +3 -3
  119. package/dist/internal/utils/encrypt-serialised.d.ts.map +1 -1
  120. package/dist/internal/utils/encrypt-serialised.js +20 -24
  121. package/dist/internal/utils/encrypt-serialised.js.map +1 -1
  122. package/dist/internal/utils/encrypt-tokenised.d.ts +2 -2
  123. package/dist/internal/utils/encrypt-tokenised.d.ts.map +1 -1
  124. package/dist/internal/utils/encrypt-tokenised.js +18 -22
  125. package/dist/internal/utils/encrypt-tokenised.js.map +1 -1
  126. package/dist/internal/utils/encryption.d.ts +3 -3
  127. package/dist/internal/utils/encryption.d.ts.map +1 -1
  128. package/dist/internal/utils/encryption.js +22 -27
  129. package/dist/internal/utils/encryption.js.map +1 -1
  130. package/dist/internal/utils/get-key/get-decryption-key.d.ts +1 -1
  131. package/dist/internal/utils/get-key/get-decryption-key.d.ts.map +1 -1
  132. package/dist/internal/utils/get-key/get-decryption-key.js +11 -15
  133. package/dist/internal/utils/get-key/get-decryption-key.js.map +1 -1
  134. package/dist/internal/utils/get-key/get-encryption-key.d.ts +1 -1
  135. package/dist/internal/utils/get-key/get-encryption-key.d.ts.map +1 -1
  136. package/dist/internal/utils/get-key/get-encryption-key.js +11 -15
  137. package/dist/internal/utils/get-key/get-encryption-key.js.map +1 -1
  138. package/dist/internal/utils/key-derivation/concat-kdf.d.ts +1 -1
  139. package/dist/internal/utils/key-derivation/concat-kdf.d.ts.map +1 -1
  140. package/dist/internal/utils/key-derivation/concat-kdf.js +3 -7
  141. package/dist/internal/utils/key-derivation/concat-kdf.js.map +1 -1
  142. package/dist/internal/utils/key-derivation/pbkdf.d.ts +1 -1
  143. package/dist/internal/utils/key-derivation/pbkdf.d.ts.map +1 -1
  144. package/dist/internal/utils/key-derivation/pbkdf.js +7 -11
  145. package/dist/internal/utils/key-derivation/pbkdf.js.map +1 -1
  146. package/dist/internal/utils/key-types/get-ec-keys.d.ts +1 -1
  147. package/dist/internal/utils/key-types/get-ec-keys.d.ts.map +1 -1
  148. package/dist/internal/utils/key-types/get-ec-keys.js +11 -16
  149. package/dist/internal/utils/key-types/get-ec-keys.js.map +1 -1
  150. package/dist/internal/utils/key-types/get-oct-keys.d.ts +1 -1
  151. package/dist/internal/utils/key-types/get-oct-keys.d.ts.map +1 -1
  152. package/dist/internal/utils/key-types/get-oct-keys.js +14 -19
  153. package/dist/internal/utils/key-types/get-oct-keys.js.map +1 -1
  154. package/dist/internal/utils/key-types/get-okp-keys.d.ts +1 -1
  155. package/dist/internal/utils/key-types/get-okp-keys.d.ts.map +1 -1
  156. package/dist/internal/utils/key-types/get-okp-keys.js +11 -16
  157. package/dist/internal/utils/key-types/get-okp-keys.js.map +1 -1
  158. package/dist/internal/utils/key-types/get-rsa-keys.d.ts +1 -1
  159. package/dist/internal/utils/key-types/get-rsa-keys.d.ts.map +1 -1
  160. package/dist/internal/utils/key-types/get-rsa-keys.js +24 -29
  161. package/dist/internal/utils/key-types/get-rsa-keys.js.map +1 -1
  162. package/dist/internal/utils/key-wrap/ecb-key-wrap.d.ts +1 -1
  163. package/dist/internal/utils/key-wrap/ecb-key-wrap.d.ts.map +1 -1
  164. package/dist/internal/utils/key-wrap/ecb-key-wrap.js +12 -17
  165. package/dist/internal/utils/key-wrap/ecb-key-wrap.js.map +1 -1
  166. package/dist/internal/utils/key-wrap/gcm-key-wrap.d.ts +1 -1
  167. package/dist/internal/utils/key-wrap/gcm-key-wrap.d.ts.map +1 -1
  168. package/dist/internal/utils/key-wrap/gcm-key-wrap.js +14 -19
  169. package/dist/internal/utils/key-wrap/gcm-key-wrap.js.map +1 -1
  170. package/dist/internal/utils/key-wrap/key-wrap.d.ts +1 -1
  171. package/dist/internal/utils/key-wrap/key-wrap.d.ts.map +1 -1
  172. package/dist/internal/utils/key-wrap/key-wrap.js +11 -16
  173. package/dist/internal/utils/key-wrap/key-wrap.js.map +1 -1
  174. package/dist/internal/utils/oct/get-oct-dir-keys.d.ts +1 -1
  175. package/dist/internal/utils/oct/get-oct-dir-keys.d.ts.map +1 -1
  176. package/dist/internal/utils/oct/get-oct-dir-keys.js +13 -18
  177. package/dist/internal/utils/oct/get-oct-dir-keys.js.map +1 -1
  178. package/dist/internal/utils/oct/get-oct-key-key-wrap.d.ts +1 -1
  179. package/dist/internal/utils/oct/get-oct-key-key-wrap.d.ts.map +1 -1
  180. package/dist/internal/utils/oct/get-oct-key-key-wrap.js +19 -24
  181. package/dist/internal/utils/oct/get-oct-key-key-wrap.js.map +1 -1
  182. package/dist/internal/utils/oct/get-oct-pbkdf-key-wrap-keys.d.ts +1 -1
  183. package/dist/internal/utils/oct/get-oct-pbkdf-key-wrap-keys.d.ts.map +1 -1
  184. package/dist/internal/utils/oct/get-oct-pbkdf-key-wrap-keys.js +25 -30
  185. package/dist/internal/utils/oct/get-oct-pbkdf-key-wrap-keys.js.map +1 -1
  186. package/dist/internal/utils/prepare-encryption.d.ts +1 -1
  187. package/dist/internal/utils/prepare-encryption.d.ts.map +1 -1
  188. package/dist/internal/utils/prepare-encryption.js +5 -9
  189. package/dist/internal/utils/prepare-encryption.js.map +1 -1
  190. package/dist/internal/utils/serialised-aes.d.ts +2 -2
  191. package/dist/internal/utils/serialised-aes.d.ts.map +1 -1
  192. package/dist/internal/utils/serialised-aes.js +19 -24
  193. package/dist/internal/utils/serialised-aes.js.map +1 -1
  194. package/dist/internal/utils/tokenised-aes.d.ts +2 -2
  195. package/dist/internal/utils/tokenised-aes.d.ts.map +1 -1
  196. package/dist/internal/utils/tokenised-aes.js +22 -27
  197. package/dist/internal/utils/tokenised-aes.js.map +1 -1
  198. package/dist/internal/utils/validate-version.js +8 -12
  199. package/dist/internal/utils/validate-version.js.map +1 -1
  200. package/dist/mocks/create-mock-aes-kit.d.ts +4 -0
  201. package/dist/mocks/create-mock-aes-kit.d.ts.map +1 -0
  202. package/dist/mocks/create-mock-aes-kit.js +81 -0
  203. package/dist/mocks/create-mock-aes-kit.js.map +1 -0
  204. package/dist/mocks/jest.d.ts +5 -0
  205. package/dist/mocks/jest.d.ts.map +1 -0
  206. package/dist/mocks/jest.js +4 -0
  207. package/dist/mocks/jest.js.map +1 -0
  208. package/dist/mocks/vitest.d.ts +6 -0
  209. package/dist/mocks/vitest.d.ts.map +1 -0
  210. package/dist/mocks/vitest.js +5 -0
  211. package/dist/mocks/vitest.js.map +1 -0
  212. package/dist/types/aes-decryption-data.d.ts +3 -3
  213. package/dist/types/aes-decryption-data.d.ts.map +1 -1
  214. package/dist/types/aes-decryption-data.js +1 -2
  215. package/dist/types/aes-encryption-data.d.ts +3 -3
  216. package/dist/types/aes-encryption-data.d.ts.map +1 -1
  217. package/dist/types/aes-encryption-data.js +1 -2
  218. package/dist/types/aes-kit.d.ts +1 -1
  219. package/dist/types/aes-kit.d.ts.map +1 -1
  220. package/dist/types/aes-kit.js +1 -2
  221. package/dist/types/content.d.ts +1 -1
  222. package/dist/types/content.d.ts.map +1 -1
  223. package/dist/types/content.js +1 -2
  224. package/dist/types/curve.js +1 -2
  225. package/dist/types/index.d.ts +7 -7
  226. package/dist/types/index.d.ts.map +1 -1
  227. package/dist/types/index.js +6 -22
  228. package/dist/types/index.js.map +1 -1
  229. package/dist/types/types.d.ts +1 -1
  230. package/dist/types/types.d.ts.map +1 -1
  231. package/dist/types/types.js +1 -2
  232. package/dist/utils/index.d.ts +2 -2
  233. package/dist/utils/index.d.ts.map +1 -1
  234. package/dist/utils/index.js +2 -18
  235. package/dist/utils/index.js.map +1 -1
  236. package/dist/utils/is-aes.d.ts +1 -1
  237. package/dist/utils/is-aes.d.ts.map +1 -1
  238. package/dist/utils/is-aes.js +4 -10
  239. package/dist/utils/is-aes.js.map +1 -1
  240. package/dist/utils/parse-aes.d.ts +1 -1
  241. package/dist/utils/parse-aes.d.ts.map +1 -1
  242. package/dist/utils/parse-aes.js +15 -19
  243. package/dist/utils/parse-aes.js.map +1 -1
  244. package/package.json +22 -23
  245. package/CHANGELOG.md +0 -165
  246. package/MERMAID.md +0 -155
  247. package/__tests__/INTEROP-RESULTS.md +0 -66
  248. package/__tests__/esm-smoke.test.ts +0 -15
  249. package/__tests__/fixtures/keys.ts +0 -60
  250. package/__tests__/helpers/buffer-utils.ts +0 -11
  251. package/__tests__/helpers/index.ts +0 -2
  252. package/__tests__/helpers/jwe-adapter.ts +0 -123
  253. package/__tests__/jose-jwe.test.ts +0 -463
  254. package/__tests__/noble-ciphers.test.ts +0 -208
  255. package/dist/mocks/index.d.ts +0 -2
  256. package/dist/mocks/index.d.ts.map +0 -1
  257. package/dist/mocks/index.js +0 -6
  258. package/dist/mocks/index.js.map +0 -1
  259. package/dist/mocks/mock-aes-kit.d.ts +0 -4
  260. package/dist/mocks/mock-aes-kit.d.ts.map +0 -1
  261. package/dist/mocks/mock-aes-kit.js +0 -74
  262. package/dist/mocks/mock-aes-kit.js.map +0 -1
  263. package/jest.config.interop.mjs +0 -24
  264. package/tsconfig.interop.json +0 -9
@@ -1,123 +0,0 @@
1
- import type { FlattenedJWE } from "jose";
2
- import type { AesDecryptionRecord } from "../../src/types/aes-decryption-data";
3
- import type { AesEncryptionRecord } from "../../src/types/aes-encryption-data";
4
-
5
- /**
6
- * Build a JWE protected header JSON string, its base64url encoding,
7
- * and the AAD buffer (ASCII bytes of the base64url-encoded header).
8
- *
9
- * Per RFC 7516 section 5.1 step 14, the JWE AAD is the ASCII representation
10
- * of the base64url-encoded protected header.
11
- *
12
- * For A*GCMKW algorithms, the key-wrap iv and tag go into the protected header
13
- * per RFC 7518 section 4.7.
14
- */
15
- export const buildProtectedHeader = (
16
- algorithm: string,
17
- encryption: string,
18
- gcmkwParams?: { iv: Buffer; tag: Buffer },
19
- ): {
20
- headerJson: string;
21
- headerB64u: string;
22
- aadBuffer: Buffer;
23
- } => {
24
- const header: Record<string, string> = { alg: algorithm, enc: encryption };
25
-
26
- if (gcmkwParams) {
27
- header.iv = gcmkwParams.iv.toString("base64url");
28
- header.tag = gcmkwParams.tag.toString("base64url");
29
- }
30
-
31
- const headerJson = JSON.stringify(header);
32
- const headerB64u = Buffer.from(headerJson, "utf8").toString("base64url");
33
- const aadBuffer = Buffer.from(headerB64u, "ascii");
34
-
35
- return { headerJson, headerB64u, aadBuffer };
36
- };
37
-
38
- /**
39
- * Convert our AesEncryptionRecord to a jose FlattenedJWE object.
40
- *
41
- * Field mapping:
42
- * - protected: base64url-encoded protected header (passed in)
43
- * - iv: base64url of record.initialisationVector
44
- * - ciphertext: base64url of record.content
45
- * - tag: base64url of record.authTag
46
- * - encrypted_key: base64url of record.publicEncryptionKey (absent for dir)
47
- */
48
- export const toFlattenedJWE = (
49
- record: AesEncryptionRecord,
50
- headerB64u: string,
51
- ): FlattenedJWE => {
52
- const jwe: FlattenedJWE = {
53
- protected: headerB64u,
54
- iv: record.initialisationVector.toString("base64url"),
55
- ciphertext: record.content.toString("base64url"),
56
- tag: record.authTag.toString("base64url"),
57
- };
58
-
59
- if (record.publicEncryptionKey) {
60
- jwe.encrypted_key = record.publicEncryptionKey.toString("base64url");
61
- }
62
-
63
- return jwe;
64
- };
65
-
66
- /**
67
- * Convert a jose FlattenedJWE back to our AesDecryptionRecord + the AAD buffer.
68
- *
69
- * Parses the protected header to extract algorithm, encryption, and optional
70
- * GCMKW parameters (iv, tag for key-wrap).
71
- *
72
- * Field mapping (inverse of toFlattenedJWE):
73
- * - content: Buffer from base64url ciphertext
74
- * - initialisationVector: Buffer from base64url iv
75
- * - authTag: Buffer from base64url tag
76
- * - publicEncryptionKey: Buffer from base64url encrypted_key (undefined for dir)
77
- * - publicEncryptionIv: Buffer from protected header iv param (GCMKW only)
78
- * - publicEncryptionTag: Buffer from protected header tag param (GCMKW only)
79
- * - encryption: enc value from protected header
80
- * - algorithm: alg value from protected header
81
- */
82
- export const fromFlattenedJWE = (
83
- jwe: FlattenedJWE,
84
- ): {
85
- record: AesDecryptionRecord;
86
- aad: Buffer;
87
- } => {
88
- if (!jwe.protected) {
89
- throw new Error("FlattenedJWE missing protected header");
90
- }
91
- if (!jwe.iv) {
92
- throw new Error("FlattenedJWE missing iv");
93
- }
94
- if (!jwe.tag) {
95
- throw new Error("FlattenedJWE missing tag");
96
- }
97
-
98
- const headerJson = Buffer.from(jwe.protected, "base64url").toString("utf8");
99
- const header = JSON.parse(headerJson) as Record<string, string>;
100
-
101
- const aad = Buffer.from(jwe.protected, "ascii");
102
-
103
- const record: AesDecryptionRecord = {
104
- algorithm: header.alg as AesDecryptionRecord["algorithm"],
105
- authTag: Buffer.from(jwe.tag, "base64url"),
106
- content: Buffer.from(jwe.ciphertext, "base64url"),
107
- contentType: (header.cty as AesDecryptionRecord["contentType"]) ?? "text/plain",
108
- encryption: header.enc as AesDecryptionRecord["encryption"],
109
- initialisationVector: Buffer.from(jwe.iv, "base64url"),
110
- keyId: header.kid ?? "jwe-interop",
111
- pbkdfIterations: undefined,
112
- pbkdfSalt: undefined,
113
- publicEncryptionIv: header.iv ? Buffer.from(header.iv, "base64url") : undefined,
114
- publicEncryptionJwk: undefined,
115
- publicEncryptionKey: jwe.encrypted_key
116
- ? Buffer.from(jwe.encrypted_key, "base64url")
117
- : undefined,
118
- publicEncryptionTag: header.tag ? Buffer.from(header.tag, "base64url") : undefined,
119
- version: "1.0",
120
- };
121
-
122
- return { record, aad };
123
- };
@@ -1,463 +0,0 @@
1
- import { createCipheriv, CipherGCM, randomBytes } from "crypto";
2
- import { FlattenedEncrypt, flattenedDecrypt } from "jose";
3
- import { encryptAes, decryptAes } from "../src/utils/private/encryption";
4
- import { createHmacAuthTag } from "../src/utils/private/data/auth-tag-hmac";
5
- import { splitContentEncryptionKey } from "../src/utils/private/data/split-content-encryption-key";
6
- import { toUint8Array } from "./helpers/buffer-utils";
7
- import {
8
- buildProtectedHeader,
9
- toFlattenedJWE,
10
- fromFlattenedJWE,
11
- } from "./helpers/jwe-adapter";
12
- import {
13
- RAW_KEY_128,
14
- RAW_KEY_192,
15
- RAW_KEY_256,
16
- RAW_KEY_256_CBC,
17
- RAW_KEY_384_CBC,
18
- RAW_KEY_512_CBC,
19
- KEK_128,
20
- KEK_192,
21
- KEK_256,
22
- createOctKryptos,
23
- } from "./fixtures/keys";
24
-
25
- const PLAINTEXT = "hello jose interop";
26
- const PLAINTEXT_BYTES = new TextEncoder().encode(PLAINTEXT);
27
-
28
- // ---------------------------------------------------------------------------
29
- // 4.1 dir + AES-GCM Cross-Reference
30
- // ---------------------------------------------------------------------------
31
-
32
- describe("jose JWE interop: dir + AES-GCM", () => {
33
- describe.each([
34
- { enc: "A128GCM" as const, key: RAW_KEY_128 },
35
- { enc: "A192GCM" as const, key: RAW_KEY_192 },
36
- { enc: "A256GCM" as const, key: RAW_KEY_256 },
37
- ])("dir + $enc", ({ enc, key }) => {
38
- test("our encrypt -> jose decrypt", async () => {
39
- const kryptos = createOctKryptos(key, "dir", enc);
40
- const { headerB64u, aadBuffer } = buildProtectedHeader("dir", enc);
41
-
42
- const record = encryptAes({
43
- data: PLAINTEXT,
44
- encryption: enc,
45
- kryptos,
46
- aad: aadBuffer,
47
- });
48
-
49
- const jwe = toFlattenedJWE(record, headerB64u);
50
- const result = await flattenedDecrypt(jwe, toUint8Array(key));
51
-
52
- expect(Buffer.from(result.plaintext).toString("utf8")).toBe(PLAINTEXT);
53
- });
54
-
55
- test("jose encrypt -> our decrypt", async () => {
56
- const kryptos = createOctKryptos(key, "dir", enc);
57
-
58
- const jwe = await new FlattenedEncrypt(PLAINTEXT_BYTES)
59
- .setProtectedHeader({ alg: "dir", enc })
60
- .encrypt(toUint8Array(key));
61
-
62
- const { record, aad } = fromFlattenedJWE(jwe);
63
-
64
- const result = decryptAes({
65
- ...record,
66
- aad,
67
- contentType: "text/plain",
68
- kryptos,
69
- });
70
-
71
- expect(result).toBe(PLAINTEXT);
72
- });
73
- });
74
- });
75
-
76
- // ---------------------------------------------------------------------------
77
- // 4.2 dir + AES-CBC-HMAC Cross-Reference
78
- // ---------------------------------------------------------------------------
79
-
80
- describe("jose JWE interop: dir + AES-CBC-HMAC", () => {
81
- describe.each([
82
- { enc: "A128CBC-HS256" as const, key: RAW_KEY_256_CBC },
83
- { enc: "A192CBC-HS384" as const, key: RAW_KEY_384_CBC },
84
- { enc: "A256CBC-HS512" as const, key: RAW_KEY_512_CBC },
85
- ])("dir + $enc", ({ enc, key }) => {
86
- test("our encrypt -> jose decrypt", async () => {
87
- const kryptos = createOctKryptos(key, "dir", enc);
88
- const { headerB64u, aadBuffer } = buildProtectedHeader("dir", enc);
89
-
90
- const record = encryptAes({
91
- data: PLAINTEXT,
92
- encryption: enc,
93
- kryptos,
94
- aad: aadBuffer,
95
- });
96
-
97
- const jwe = toFlattenedJWE(record, headerB64u);
98
- const result = await flattenedDecrypt(jwe, toUint8Array(key));
99
-
100
- expect(Buffer.from(result.plaintext).toString("utf8")).toBe(PLAINTEXT);
101
- });
102
-
103
- test("jose encrypt -> our decrypt", async () => {
104
- const kryptos = createOctKryptos(key, "dir", enc);
105
-
106
- const jwe = await new FlattenedEncrypt(PLAINTEXT_BYTES)
107
- .setProtectedHeader({ alg: "dir", enc })
108
- .encrypt(toUint8Array(key));
109
-
110
- const { record, aad } = fromFlattenedJWE(jwe);
111
-
112
- const result = decryptAes({
113
- ...record,
114
- aad,
115
- contentType: "text/plain",
116
- kryptos,
117
- });
118
-
119
- expect(result).toBe(PLAINTEXT);
120
- });
121
- });
122
- });
123
-
124
- // ---------------------------------------------------------------------------
125
- // 4.3 A*KW + AES-GCM Cross-Reference
126
- // ---------------------------------------------------------------------------
127
-
128
- describe("jose JWE interop: A*KW + AES-GCM", () => {
129
- describe.each([
130
- { alg: "A128KW" as const, kek: KEK_128 },
131
- { alg: "A192KW" as const, kek: KEK_192 },
132
- { alg: "A256KW" as const, kek: KEK_256 },
133
- ])("$alg", ({ alg, kek }) => {
134
- describe.each([{ enc: "A128GCM" as const }, { enc: "A256GCM" as const }])(
135
- "+ $enc",
136
- ({ enc }) => {
137
- test("our encrypt -> jose decrypt", async () => {
138
- const kryptos = createOctKryptos(kek, alg, enc);
139
- const { headerB64u, aadBuffer } = buildProtectedHeader(alg, enc);
140
-
141
- const record = encryptAes({
142
- data: PLAINTEXT,
143
- encryption: enc,
144
- kryptos,
145
- aad: aadBuffer,
146
- });
147
-
148
- const jwe = toFlattenedJWE(record, headerB64u);
149
- const result = await flattenedDecrypt(jwe, toUint8Array(kek));
150
-
151
- expect(Buffer.from(result.plaintext).toString("utf8")).toBe(PLAINTEXT);
152
- });
153
-
154
- test("jose encrypt -> our decrypt", async () => {
155
- const kryptos = createOctKryptos(kek, alg, enc);
156
-
157
- const jwe = await new FlattenedEncrypt(PLAINTEXT_BYTES)
158
- .setProtectedHeader({ alg, enc })
159
- .encrypt(toUint8Array(kek));
160
-
161
- const { record, aad } = fromFlattenedJWE(jwe);
162
-
163
- const result = decryptAes({
164
- ...record,
165
- aad,
166
- contentType: "text/plain",
167
- kryptos,
168
- });
169
-
170
- expect(result).toBe(PLAINTEXT);
171
- });
172
- },
173
- );
174
- });
175
- });
176
-
177
- // ---------------------------------------------------------------------------
178
- // 4.4 A*KW + AES-CBC-HMAC Cross-Reference
179
- // ---------------------------------------------------------------------------
180
-
181
- describe("jose JWE interop: A*KW + AES-CBC-HMAC", () => {
182
- describe.each([
183
- { alg: "A128KW" as const, enc: "A128CBC-HS256" as const, kek: KEK_128 },
184
- { alg: "A192KW" as const, enc: "A192CBC-HS384" as const, kek: KEK_192 },
185
- { alg: "A256KW" as const, enc: "A256CBC-HS512" as const, kek: KEK_256 },
186
- ])("$alg + $enc", ({ alg, enc, kek }) => {
187
- test("our encrypt -> jose decrypt", async () => {
188
- const kryptos = createOctKryptos(kek, alg, enc);
189
- const { headerB64u, aadBuffer } = buildProtectedHeader(alg, enc);
190
-
191
- const record = encryptAes({
192
- data: PLAINTEXT,
193
- encryption: enc,
194
- kryptos,
195
- aad: aadBuffer,
196
- });
197
-
198
- const jwe = toFlattenedJWE(record, headerB64u);
199
- const result = await flattenedDecrypt(jwe, toUint8Array(kek));
200
-
201
- expect(Buffer.from(result.plaintext).toString("utf8")).toBe(PLAINTEXT);
202
- });
203
-
204
- test("jose encrypt -> our decrypt", async () => {
205
- const kryptos = createOctKryptos(kek, alg, enc);
206
-
207
- const jwe = await new FlattenedEncrypt(PLAINTEXT_BYTES)
208
- .setProtectedHeader({ alg, enc })
209
- .encrypt(toUint8Array(kek));
210
-
211
- const { record, aad } = fromFlattenedJWE(jwe);
212
-
213
- const result = decryptAes({
214
- ...record,
215
- aad,
216
- contentType: "text/plain",
217
- kryptos,
218
- });
219
-
220
- expect(result).toBe(PLAINTEXT);
221
- });
222
- });
223
- });
224
-
225
- // ---------------------------------------------------------------------------
226
- // 4.5 A*GCMKW + AES-GCM Cross-Reference
227
- // ---------------------------------------------------------------------------
228
-
229
- describe("jose JWE interop: A*GCMKW + AES-GCM", () => {
230
- describe.each([
231
- { alg: "A128GCMKW" as const, kek: KEK_128 },
232
- { alg: "A256GCMKW" as const, kek: KEK_256 },
233
- ])("$alg + A256GCM", ({ alg, kek }) => {
234
- const enc = "A256GCM" as const;
235
-
236
- test("jose encrypt -> our decrypt", async () => {
237
- const kryptos = createOctKryptos(kek, alg, enc);
238
-
239
- const jwe = await new FlattenedEncrypt(PLAINTEXT_BYTES)
240
- .setProtectedHeader({ alg, enc })
241
- .encrypt(toUint8Array(kek));
242
-
243
- const { record, aad } = fromFlattenedJWE(jwe);
244
-
245
- const result = decryptAes({
246
- ...record,
247
- aad,
248
- contentType: "text/plain",
249
- kryptos,
250
- });
251
-
252
- expect(result).toBe(PLAINTEXT);
253
- });
254
-
255
- // Our encrypt -> jose decrypt for GCMKW has a circular dependency:
256
- // The protected header must contain the key-wrap iv and tag (per RFC 7518 section 4.7),
257
- // but the content encryption AAD is computed from the protected header (per RFC 7516
258
- // section 5.1 step 14). Our encryptAes() generates the key-wrap params and encrypts
259
- // content in a single pass, so we cannot know the final header (and therefore the
260
- // correct AAD) before encryption.
261
- //
262
- // A two-pass approach (encrypt once to get kw params, build header, re-encrypt with
263
- // correct AAD) would require exposing the CEK from the first pass, which our API
264
- // does not currently support via the public encryptAes interface.
265
- //
266
- // The jose->ours direction above validates that our decryption is fully compatible.
267
- // Byte-level correctness of our GCM key-wrap is separately validated in the
268
- // noble-ciphers cross-reference tests.
269
- test("our encrypt -> jose decrypt", async () => {
270
- const kryptos = createOctKryptos(kek, alg, enc);
271
-
272
- // Perform encryption without AAD first to get the key-wrap parameters
273
- const record = encryptAes({
274
- data: PLAINTEXT,
275
- encryption: enc,
276
- kryptos,
277
- });
278
-
279
- // Build the protected header including the GCMKW iv and tag
280
- const { headerB64u, aadBuffer } = buildProtectedHeader(alg, enc, {
281
- iv: record.publicEncryptionIv!,
282
- tag: record.publicEncryptionTag!,
283
- });
284
-
285
- // Re-encrypt with correct AAD using the same CEK that was wrapped.
286
- // We can recover the CEK by unwrapping the encrypted_key.
287
- const unwrapKryptos = createOctKryptos(kek, alg, enc);
288
- const { contentEncryptionKey } = (
289
- await import("../src/utils/private/key-wrap/gcm-key-wrap")
290
- ).gcmKeyUnwrap({
291
- keyEncryptionKey: kek,
292
- kryptos: unwrapKryptos,
293
- publicEncryptionIv: record.publicEncryptionIv!,
294
- publicEncryptionKey: record.publicEncryptionKey!,
295
- publicEncryptionTag: record.publicEncryptionTag!,
296
- });
297
-
298
- // Re-encrypt content with the recovered CEK and correct AAD
299
- const { encryptionKey } = splitContentEncryptionKey(enc, contentEncryptionKey);
300
- const iv = randomBytes(12);
301
- const cipher = createCipheriv("aes-256-gcm", encryptionKey, iv, {
302
- authTagLength: 16,
303
- }) as CipherGCM;
304
- cipher.setAAD(aadBuffer);
305
-
306
- const plaintextBuf = Buffer.from(PLAINTEXT, "utf8");
307
- const ciphertext = Buffer.concat([cipher.update(plaintextBuf), cipher.final()]);
308
- const authTag = cipher.getAuthTag();
309
-
310
- const jwe = {
311
- protected: headerB64u,
312
- iv: iv.toString("base64url"),
313
- ciphertext: ciphertext.toString("base64url"),
314
- tag: authTag.toString("base64url"),
315
- encrypted_key: record.publicEncryptionKey!.toString("base64url"),
316
- };
317
-
318
- const result = await flattenedDecrypt(jwe, toUint8Array(kek));
319
- expect(Buffer.from(result.plaintext).toString("utf8")).toBe(PLAINTEXT);
320
- });
321
- });
322
- });
323
-
324
- // ---------------------------------------------------------------------------
325
- // 4.6 Deterministic Pinned Tests
326
- // ---------------------------------------------------------------------------
327
- //
328
- // jose v6 does not allow setContentEncryptionKey() with alg: "dir".
329
- // We use A256KW / A128KW key-wrap algorithms instead, which do allow CEK
330
- // pinning. This still validates byte-identical ciphertext because the
331
- // content encryption is the same regardless of the key management algorithm.
332
- // ---------------------------------------------------------------------------
333
-
334
- describe("jose JWE interop: deterministic pinned tests", () => {
335
- describe("A256KW + A256GCM", () => {
336
- const alg = "A256KW" as const;
337
- const enc = "A256GCM" as const;
338
- const kek = KEK_256;
339
- const cek = Buffer.from(
340
- "e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff00",
341
- "hex",
342
- );
343
- const iv = Buffer.from("0a0b0c0d0e0f10111213141516", "hex").subarray(0, 12);
344
- const plaintextBuf = Buffer.from(PLAINTEXT, "utf8");
345
-
346
- test("byte-identical ciphertext and auth tag", async () => {
347
- // jose: encrypt with pinned CEK and IV
348
- const jwe = await new FlattenedEncrypt(PLAINTEXT_BYTES)
349
- .setProtectedHeader({ alg, enc })
350
- .setContentEncryptionKey(toUint8Array(cek))
351
- .setInitializationVector(toUint8Array(iv))
352
- .encrypt(toUint8Array(kek));
353
-
354
- // The AAD is the ASCII bytes of the base64url-encoded protected header
355
- const joseAad = Buffer.from(jwe.protected!, "ascii");
356
-
357
- // Our side: raw createCipheriv with the same CEK, IV, and AAD
358
- const cipher = createCipheriv("aes-256-gcm", cek, iv, {
359
- authTagLength: 16,
360
- }) as CipherGCM;
361
- cipher.setAAD(joseAad);
362
-
363
- const ourCiphertext = Buffer.concat([cipher.update(plaintextBuf), cipher.final()]);
364
- const ourTag = cipher.getAuthTag();
365
-
366
- const joseCiphertext = Buffer.from(jwe.ciphertext, "base64url");
367
- const joseTag = Buffer.from(jwe.tag!, "base64url");
368
-
369
- expect(ourCiphertext.equals(joseCiphertext)).toBe(true);
370
- expect(ourTag.equals(joseTag)).toBe(true);
371
- });
372
-
373
- test("round-trip with pinned values through decryptAes", async () => {
374
- // jose: encrypt with pinned CEK and IV
375
- const jwe = await new FlattenedEncrypt(PLAINTEXT_BYTES)
376
- .setProtectedHeader({ alg, enc })
377
- .setContentEncryptionKey(toUint8Array(cek))
378
- .setInitializationVector(toUint8Array(iv))
379
- .encrypt(toUint8Array(kek));
380
-
381
- // Parse with our adapter and decrypt
382
- const kryptos = createOctKryptos(kek, alg, enc);
383
- const { record, aad } = fromFlattenedJWE(jwe);
384
-
385
- const result = decryptAes({
386
- ...record,
387
- aad,
388
- contentType: "text/plain",
389
- kryptos,
390
- });
391
-
392
- expect(result).toBe(PLAINTEXT);
393
- });
394
- });
395
-
396
- describe("A128KW + A128CBC-HS256", () => {
397
- const alg = "A128KW" as const;
398
- const enc = "A128CBC-HS256" as const;
399
- const kek = KEK_128;
400
- // A128CBC-HS256 CEK is 32 bytes: first 16 = HMAC key, last 16 = AES key
401
- const cek = Buffer.from(
402
- "a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0",
403
- "hex",
404
- );
405
- const iv = Buffer.alloc(16, 0xdd);
406
- const plaintextBuf = Buffer.from(PLAINTEXT, "utf8");
407
-
408
- test("byte-identical ciphertext and auth tag", async () => {
409
- // jose: encrypt with pinned CEK and IV
410
- const jwe = await new FlattenedEncrypt(PLAINTEXT_BYTES)
411
- .setProtectedHeader({ alg, enc })
412
- .setContentEncryptionKey(toUint8Array(cek))
413
- .setInitializationVector(toUint8Array(iv))
414
- .encrypt(toUint8Array(kek));
415
-
416
- const joseAad = Buffer.from(jwe.protected!, "ascii");
417
-
418
- // Split CEK per RFC 7518 Section 5.2
419
- const { encryptionKey, hashKey } = splitContentEncryptionKey(enc, cek);
420
-
421
- // Our side: raw createCipheriv (CBC) with same key and IV
422
- const cipher = createCipheriv("aes-128-cbc", encryptionKey, iv);
423
- const ourCiphertext = Buffer.concat([cipher.update(plaintextBuf), cipher.final()]);
424
-
425
- // HMAC auth tag per RFC 7518 Section 5.2.2.1
426
- const ourTag = createHmacAuthTag({
427
- aad: joseAad,
428
- content: ourCiphertext,
429
- encryption: enc,
430
- hashKey,
431
- initialisationVector: iv,
432
- });
433
-
434
- const joseCiphertext = Buffer.from(jwe.ciphertext, "base64url");
435
- const joseTag = Buffer.from(jwe.tag!, "base64url");
436
-
437
- expect(ourCiphertext.equals(joseCiphertext)).toBe(true);
438
- expect(ourTag.equals(joseTag)).toBe(true);
439
- });
440
-
441
- test("round-trip with pinned values through decryptAes", async () => {
442
- // jose: encrypt with pinned CEK and IV
443
- const jwe = await new FlattenedEncrypt(PLAINTEXT_BYTES)
444
- .setProtectedHeader({ alg, enc })
445
- .setContentEncryptionKey(toUint8Array(cek))
446
- .setInitializationVector(toUint8Array(iv))
447
- .encrypt(toUint8Array(kek));
448
-
449
- // Parse with our adapter and decrypt
450
- const kryptos = createOctKryptos(kek, alg, enc);
451
- const { record, aad } = fromFlattenedJWE(jwe);
452
-
453
- const result = decryptAes({
454
- ...record,
455
- aad,
456
- contentType: "text/plain",
457
- kryptos,
458
- });
459
-
460
- expect(result).toBe(PLAINTEXT);
461
- });
462
- });
463
- });