crypto-utils.js 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", {
  3. value: true
  4. });
  5. exports.encryptWithSecret = encryptWithSecret;
  6. exports.decryptWithSecret = decryptWithSecret;
  7. var _crypto = _interopRequireDefault(require("crypto"));
  8. function _interopRequireDefault(obj) {
  9. return obj && obj.__esModule ? obj : {
  10. default: obj
  11. };
  12. }
  13. // Background:
  14. // https://security.stackexchange.com/questions/184305/why-would-i-ever-use-aes-256-cbc-if-aes-256-gcm-is-more-secure
  15. const CIPHER_ALGORITHM = `aes-256-gcm`, CIPHER_KEY_LENGTH = 32, CIPHER_IV_LENGTH = 16, CIPHER_TAG_LENGTH = 16, CIPHER_SALT_LENGTH = 64;
  16. const PBKDF2_ITERATIONS = 100000 // https://support.1password.com/pbkdf2/
  17. ;
  18. function encryptWithSecret(secret, data) {
  19. const iv = _crypto.default.randomBytes(CIPHER_IV_LENGTH);
  20. const salt = _crypto.default.randomBytes(CIPHER_SALT_LENGTH);
  21. // https://nodejs.org/api/crypto.html#crypto_crypto_pbkdf2sync_password_salt_iterations_keylen_digest
  22. const key = _crypto.default.pbkdf2Sync(secret, salt, PBKDF2_ITERATIONS, CIPHER_KEY_LENGTH, `sha512`);
  23. const cipher = _crypto.default.createCipheriv(CIPHER_ALGORITHM, key, iv);
  24. const encrypted = Buffer.concat([
  25. cipher.update(data, `utf8`),
  26. cipher.final()
  27. ]);
  28. // https://nodejs.org/api/crypto.html#crypto_cipher_getauthtag
  29. const tag = cipher.getAuthTag();
  30. return Buffer.concat([
  31. // Data as required by:
  32. // Salt for Key: https://nodejs.org/api/crypto.html#crypto_crypto_pbkdf2sync_password_salt_iterations_keylen_digest
  33. // IV: https://nodejs.org/api/crypto.html#crypto_class_decipher
  34. // Tag: https://nodejs.org/api/crypto.html#crypto_decipher_setauthtag_buffer
  35. salt,
  36. iv,
  37. tag,
  38. encrypted,
  39. ]).toString(`hex`);
  40. }
  41. function decryptWithSecret(secret, encryptedData) {
  42. const buffer = Buffer.from(encryptedData, `hex`);
  43. const salt = buffer.slice(0, CIPHER_SALT_LENGTH);
  44. const iv = buffer.slice(CIPHER_SALT_LENGTH, CIPHER_SALT_LENGTH + CIPHER_IV_LENGTH);
  45. const tag = buffer.slice(CIPHER_SALT_LENGTH + CIPHER_IV_LENGTH, CIPHER_SALT_LENGTH + CIPHER_IV_LENGTH + CIPHER_TAG_LENGTH);
  46. const encrypted = buffer.slice(CIPHER_SALT_LENGTH + CIPHER_IV_LENGTH + CIPHER_TAG_LENGTH);
  47. // https://nodejs.org/api/crypto.html#crypto_crypto_pbkdf2sync_password_salt_iterations_keylen_digest
  48. const key = _crypto.default.pbkdf2Sync(secret, salt, PBKDF2_ITERATIONS, CIPHER_KEY_LENGTH, `sha512`);
  49. const decipher = _crypto.default.createDecipheriv(CIPHER_ALGORITHM, key, iv);
  50. decipher.setAuthTag(tag);
  51. return decipher.update(encrypted) + decipher.final(`utf8`);
  52. }
  53. //# sourceMappingURL=crypto-utils.js.map