AES.js 3.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. const aesjs = require('aes-js');
  2. class AES {
  3. /**
  4. * Decrypts the given text in 16-bytes blocks by using the given key and 32-bytes initialization vector
  5. * @param cipherText {Buffer}
  6. * @param key {Buffer}
  7. * @param iv {Buffer}
  8. * @returns {Buffer}
  9. */
  10. static decryptIge(cipherText, key, iv) {
  11. let iv1 = iv.slice(0, Math.floor(iv.length / 2));
  12. let iv2 = iv.slice(Math.floor(iv.length / 2));
  13. let plainText = new Array(cipherText.length).fill(0);
  14. let aes = new aesjs.AES(key);
  15. let blocksCount = Math.floor(plainText.length / 16);
  16. let cipherTextBlock = new Array(16).fill(0);
  17. for (let blockIndex = 0; blockIndex < blocksCount; blockIndex++) {
  18. for (let i = 0; i < 16; i++) {
  19. cipherTextBlock[i] = cipherText[blockIndex * 16 + i] ^ iv2[i];
  20. }
  21. let plainTextBlock = aes.decrypt(cipherTextBlock);
  22. for (let i = 0; i < 16; i++) {
  23. plainTextBlock[i] ^= iv1[i];
  24. }
  25. iv1 = cipherText.slice(blockIndex * 16, blockIndex * 16 + 16);
  26. iv2 = plainTextBlock.slice(0, 16);
  27. plainText = new Uint8Array([
  28. ...plainText.slice(0, blockIndex * 16),
  29. ...plainTextBlock.slice(0, 16),
  30. ...plainText.slice(blockIndex * 16 + 16)
  31. ]);
  32. }
  33. return Buffer.from(plainText);
  34. }
  35. /**
  36. * Encrypts the given text in 16-bytes blocks by using the given key and 32-bytes initialization vector
  37. * @param plainText {Buffer}
  38. * @param key {Buffer}
  39. * @param iv {Buffer}
  40. * @returns {Buffer}
  41. */
  42. static encryptIge(plainText, key, iv) {
  43. if (plainText.length % 16 !== 0) {
  44. let padding = new Uint8Array(16 - plainText.length % 16);
  45. plainText = new Uint8Array([
  46. ...plainText,
  47. ...padding,
  48. ]);
  49. }
  50. let iv1 = iv.slice(0, Math.floor(iv.length / 2));
  51. let iv2 = iv.slice(Math.floor(iv.length / 2));
  52. let aes = new aesjs.AES(key);
  53. let blocksCount = Math.floor(plainText.length / 16);
  54. let cipherText = new Array(plainText.length).fill(0);
  55. for (let blockIndex = 0; blockIndex < blocksCount; blockIndex++) {
  56. let plainTextBlock = plainText.slice(blockIndex * 16, blockIndex * 16 + 16);
  57. for (let i = 0; i < 16; i++) {
  58. plainTextBlock[i] ^= iv1[i];
  59. }
  60. let cipherTextBlock = aes.encrypt(plainTextBlock);
  61. for (let i = 0; i < 16; i++) {
  62. cipherTextBlock[i] ^= iv2[i];
  63. }
  64. iv1 = cipherTextBlock.slice(0, 16);
  65. iv2 = plainText.slice(blockIndex * 16, blockIndex * 16 + 16);
  66. cipherText = new Uint8Array([
  67. ...cipherText.slice(0, blockIndex * 16),
  68. ...cipherTextBlock.slice(0, 16),
  69. ...cipherText.slice(blockIndex * 16 + 16)
  70. ]);
  71. }
  72. return Buffer.from(cipherText);
  73. }
  74. }
  75. exports.AES = AES;