CryptUtils.ts 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. import { inject, injectable } from 'inversify';
  2. import { ServiceIdentifiers } from '../container/ServiceIdentifiers';
  3. import { ICryptUtils } from '../interfaces/utils/ICryptUtils';
  4. import { IRandomGenerator } from '../interfaces/utils/IRandomGenerator';
  5. import { RandomGenerator } from './RandomGenerator';
  6. import { Utils } from './Utils';
  7. @injectable()
  8. export class CryptUtils implements ICryptUtils {
  9. /**
  10. * @type {IRandomGenerator}
  11. */
  12. private readonly randomGenerator: IRandomGenerator;
  13. /**
  14. * @param {IRandomGenerator} randomGenerator
  15. */
  16. constructor (
  17. @inject(ServiceIdentifiers.IRandomGenerator) randomGenerator: IRandomGenerator
  18. ) {
  19. this.randomGenerator = randomGenerator;
  20. }
  21. // tslint:disable
  22. /**
  23. * @param {string} string
  24. * @returns {string}
  25. */
  26. public btoa (string: string): string {
  27. const chars: string = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';
  28. let output: string = '';
  29. string = encodeURIComponent(string).replace(/%([0-9A-F]{2})/g, (match, p1) => {
  30. return String.fromCharCode(parseInt(`${Utils.hexadecimalPrefix}${p1}`));
  31. });
  32. for (
  33. let block: number | undefined, charCode: number, idx: number = 0, map: string = chars;
  34. string.charAt(idx | 0) || (map = '=', idx % 1);
  35. output += map.charAt(63 & block >> 8 - idx % 1 * 8)
  36. ) {
  37. charCode = string.charCodeAt(idx += 3/4);
  38. if (charCode > 0xFF) {
  39. throw new Error("'btoa' failed: The string to be encoded contains characters outside of the Latin1 range.");
  40. }
  41. block = <number>block << 8 | charCode;
  42. }
  43. return output;
  44. }
  45. // tslint:enable
  46. /**
  47. * Hides string inside a other random string with larger length
  48. *
  49. * @param {string} str
  50. * @param {number} length
  51. * @returns {[string , string]}
  52. */
  53. public hideString (str: string, length: number): [string, string] {
  54. const escapeRegExp: (s: string) => string = (s: string) =>
  55. s.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
  56. const randomMerge: (s1: string, s2: string) => string = (s1: string, s2: string): string => {
  57. let i1: number = -1;
  58. let i2: number = -1;
  59. let result: string = '';
  60. while (i1 < s1.length || i2 < s2.length) {
  61. if (this.randomGenerator.getMathRandom() < 0.5 && i2 < s2.length) {
  62. result += s2.charAt(++i2);
  63. } else {
  64. result += s1.charAt(++i1);
  65. }
  66. }
  67. return result;
  68. };
  69. const randomString: string = this.randomGenerator.getRandomGenerator().string({
  70. length: length,
  71. pool: RandomGenerator.randomGeneratorPool
  72. });
  73. let randomStringDiff: string = randomString.replace(
  74. new RegExp(`[${escapeRegExp(str)}]`, 'g'),
  75. ''
  76. );
  77. const randomStringDiffArray: string[] = randomStringDiff.split('');
  78. this.randomGenerator.getRandomGenerator().shuffle(randomStringDiffArray);
  79. randomStringDiff = randomStringDiffArray.join('');
  80. return [randomMerge(str, randomStringDiff), randomStringDiff];
  81. }
  82. // tslint:disable
  83. /**
  84. * RC4 symmetric cipher encryption/decryption
  85. * https://gist.github.com/farhadi/2185197
  86. *
  87. * @param {string} string
  88. * @param {string} key
  89. * @returns {string}
  90. */
  91. public rc4 (string: string, key: string): string {
  92. let s: number[] = [],
  93. j: number = 0,
  94. x: number,
  95. result: string = '';
  96. for (var i = 0; i < 256; i++) {
  97. s[i] = i;
  98. }
  99. for (i = 0; i < 256; i++) {
  100. j = (j + s[i] + key.charCodeAt(i % key.length)) % 256;
  101. x = s[i];
  102. s[i] = s[j];
  103. s[j] = x;
  104. }
  105. i = 0;
  106. j = 0;
  107. for (let y = 0; y < string.length; y++) {
  108. i = (i + 1) % 256;
  109. j = (j + s[i]) % 256;
  110. x = s[i];
  111. s[i] = s[j];
  112. s[j] = x;
  113. result += String.fromCharCode(string.charCodeAt(y) ^ s[(s[i] + s[j]) % 256]);
  114. }
  115. return result;
  116. }
  117. // tslint:enable
  118. }