Crypto-JS всегда возвращает новый хеш - PullRequest
4 голосов
/ 26 сентября 2019

Я хочу использовать crypto-js в моем приложении angular 8.
это мой пример кода:

import {Injectable} from '@angular/core';
import * as CryptoJS from 'crypto-js';

@Injectable()
export class HprotoService {

  public enc(msg: string): string {
    return CryptoJS.AES.encrypt(msg, '1234').toString();
  }

  public dec(encMsg: string): string {
    return CryptoJS.AES.decrypt(encMsg, '1234').toString(CryptoJS.enc.Utf8);
  }
}

и мой компонент:

import {Component} from '@angular/core';
import {HprotoService} from './hproto.service';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss']
})
export class AppComponent {

  private hproto: HprotoService;

  constructor(hproto: HprotoService) {
    this.hproto = hproto;
  }

  public encrypt() {
    console.log(this.hproto.enc('Hello dear !!!'));
  }
}

Моя проблема в том, что Crypto-JS всегда возвращает разные хэши в этом примере!

U2FsdGVkX19E9JKokPiRUZlrWsykZqAIEVw7ftbBbiA =
U2FsdGVkX1 + 8qW19xOpLCy1Zt5lcyxE3LIKrhs5VmjI =
U2FsdGVkX1 / I2AuJM3jBgHuASmWQvkgmaL0RMsR2LXA =
U2FsdGVkX1 + tR17ftLYsWGoEcRA0 + zmSjkLHJE3zul0 =

Я думаю, что эта библиотека добавить случайная сольна мой пароль.
Как отключить эту функцию?

1 Ответ

3 голосов
/ 27 сентября 2019

AES предназначен для генерирования случайных выходных данных, которые являются симметричными (которые могут быть расшифрованы)

CryptoJS AES использует Math.random() вызовы для генерации матрицы / соли во время шифрования, и эта случайность равнавключенный в зашифрованный результат, именно так расшифровка может «расшифровать» зашифрованные данные.

Вы можете либо разветвить библиотеку CryptoJS и заменить использование Math.random своим собственным семенем или вы можете изменить результат Math.random во время выполнения на время шифрования .

Благодаря Javascript вы можете назначить пользовательский код для native function.

Вот вариант № 2.Он всегда будет возвращать один и тот же вывод, он использует функцию fakeMathRandom.Это временно изменит результат Math.random на время функции callBack

функция fakeMathRandom

function fakeMathRandom(callBack) {
     if(!callBack) throw new Error("Must provide callBack function");
     //fake predefined output setup
     let seed=0;
     const randomOutputs = [0.04,0.08,0.15,0.16,0.23,0.42,0.52,0.65,0.79,0.89];
     //save nativeFunction
     const Math_random = Math.random;
     //change nativeFunction
     Math.random = function() {return randomOutputs[seed++ % 10];}
     //runs the callback
     const callbackOutput = callBack();
     //restore nativeFunction
     Math.random = Math_random; 
     return callbackOutput;
}

Использование

var encrypted = fakeMathRandom(() => CryptoJS.AES.encrypt(text, key));

Полный демонстрационный код:

function fakeMathRandom(callBack) {
  if(!callBack) throw new Error("Must provide callBack function");
	let seed=0;
  const randomOutputs = [0.04,0.08,0.15,0.16,0.23,0.42,0.52,0.65,0.79,0.89];
  const Math_random = Math.random;
  Math.random = function() {return randomOutputs[seed++ % 10];}
  const callbackOutput = callBack();
  Math.random = Math_random;
  return callbackOutput;
}

var text = "Text to crypt!!!.";
var key  = 'secret';

var encrypted = fakeMathRandom(() => CryptoJS.AES.encrypt(text, key)); //This will always return U2FsdGVkX18KPXCjFHrhR4Q5zBbjCf+I/m/w9jbS3EuvE59kzUxK45FrGHDpqalt
var encrypted2 = fakeMathRandom(() => CryptoJS.AES.encrypt(text, key));
var encrypted3 = fakeMathRandom(() => CryptoJS.AES.encrypt(text, key));

var decrypted = CryptoJS.AES.decrypt(encrypted, key).toString(CryptoJS.enc.Utf8);


document.getElementById('encrypted').innerHTML = encrypted
document.getElementById('encrypted2').innerHTML = encrypted2
document.getElementById('encrypted3').innerHTML = encrypted3
document.getElementById('decrypted').innerHTML = decrypted
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.2/rollups/aes.js"></script>
<div id="encrypted"></div>
<div id="encrypted2"></div>
<div id="encrypted3"></div>
<div id="decrypted"></div>

Я надеюсь, что это решит вашу проблему!

...