decrypt.js 3.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", { value: true });
  3. const crypto_1 = require("crypto");
  4. const check_iv_length_js_1 = require("../lib/check_iv_length.js");
  5. const check_cek_length_js_1 = require("./check_cek_length.js");
  6. const buffer_utils_js_1 = require("../lib/buffer_utils.js");
  7. const errors_js_1 = require("../util/errors.js");
  8. const timing_safe_equal_js_1 = require("./timing_safe_equal.js");
  9. const cbc_tag_js_1 = require("./cbc_tag.js");
  10. const webcrypto_js_1 = require("./webcrypto.js");
  11. const crypto_key_js_1 = require("../lib/crypto_key.js");
  12. const is_key_object_js_1 = require("./is_key_object.js");
  13. const invalid_key_input_js_1 = require("../lib/invalid_key_input.js");
  14. const ciphers_js_1 = require("./ciphers.js");
  15. const is_key_like_js_1 = require("./is_key_like.js");
  16. function cbcDecrypt(enc, cek, ciphertext, iv, tag, aad) {
  17. const keySize = parseInt(enc.slice(1, 4), 10);
  18. if ((0, is_key_object_js_1.default)(cek)) {
  19. cek = cek.export();
  20. }
  21. const encKey = cek.subarray(keySize >> 3);
  22. const macKey = cek.subarray(0, keySize >> 3);
  23. const macSize = parseInt(enc.slice(-3), 10);
  24. const algorithm = `aes-${keySize}-cbc`;
  25. if (!(0, ciphers_js_1.default)(algorithm)) {
  26. throw new errors_js_1.JOSENotSupported(`alg ${enc} is not supported by your javascript runtime`);
  27. }
  28. const expectedTag = (0, cbc_tag_js_1.default)(aad, iv, ciphertext, macSize, macKey, keySize);
  29. let macCheckPassed;
  30. try {
  31. macCheckPassed = (0, timing_safe_equal_js_1.default)(tag, expectedTag);
  32. }
  33. catch {
  34. }
  35. if (!macCheckPassed) {
  36. throw new errors_js_1.JWEDecryptionFailed();
  37. }
  38. let plaintext;
  39. try {
  40. const decipher = (0, crypto_1.createDecipheriv)(algorithm, encKey, iv);
  41. plaintext = (0, buffer_utils_js_1.concat)(decipher.update(ciphertext), decipher.final());
  42. }
  43. catch {
  44. }
  45. if (!plaintext) {
  46. throw new errors_js_1.JWEDecryptionFailed();
  47. }
  48. return plaintext;
  49. }
  50. function gcmDecrypt(enc, cek, ciphertext, iv, tag, aad) {
  51. const keySize = parseInt(enc.slice(1, 4), 10);
  52. const algorithm = `aes-${keySize}-gcm`;
  53. if (!(0, ciphers_js_1.default)(algorithm)) {
  54. throw new errors_js_1.JOSENotSupported(`alg ${enc} is not supported by your javascript runtime`);
  55. }
  56. try {
  57. const decipher = (0, crypto_1.createDecipheriv)(algorithm, cek, iv, { authTagLength: 16 });
  58. decipher.setAuthTag(tag);
  59. if (aad.byteLength) {
  60. decipher.setAAD(aad, { plaintextLength: ciphertext.length });
  61. }
  62. const plaintext = decipher.update(ciphertext);
  63. decipher.final();
  64. return plaintext;
  65. }
  66. catch {
  67. throw new errors_js_1.JWEDecryptionFailed();
  68. }
  69. }
  70. const decrypt = (enc, cek, ciphertext, iv, tag, aad) => {
  71. let key;
  72. if ((0, webcrypto_js_1.isCryptoKey)(cek)) {
  73. (0, crypto_key_js_1.checkEncCryptoKey)(cek, enc, 'decrypt');
  74. key = crypto_1.KeyObject.from(cek);
  75. }
  76. else if (cek instanceof Uint8Array || (0, is_key_object_js_1.default)(cek)) {
  77. key = cek;
  78. }
  79. else {
  80. throw new TypeError((0, invalid_key_input_js_1.default)(cek, ...is_key_like_js_1.types, 'Uint8Array'));
  81. }
  82. (0, check_cek_length_js_1.default)(enc, key);
  83. (0, check_iv_length_js_1.default)(enc, iv);
  84. switch (enc) {
  85. case 'A128CBC-HS256':
  86. case 'A192CBC-HS384':
  87. case 'A256CBC-HS512':
  88. return cbcDecrypt(enc, key, ciphertext, iv, tag, aad);
  89. case 'A128GCM':
  90. case 'A192GCM':
  91. case 'A256GCM':
  92. return gcmDecrypt(enc, key, ciphertext, iv, tag, aad);
  93. default:
  94. throw new errors_js_1.JOSENotSupported('Unsupported JWE Content Encryption Algorithm');
  95. }
  96. };
  97. exports.default = decrypt;