最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Crypto-JS always return new hash - Stack Overflow

programmeradmin6浏览0评论

I want to use crypto-js on my angular 8 application .
this is my example code :

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);
  }
}

and my ponent :

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

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

  private hproto: HprotoService;

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

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

My problem is Crypto-JS always return different hash on this example !

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

I think this library add random salt on my password .
How to disable this feature ?

I want to use crypto-js on my angular 8 application .
this is my example code :

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);
  }
}

and my ponent :

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

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

  private hproto: HprotoService;

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

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

My problem is Crypto-JS always return different hash on this example !

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

I think this library add random salt on my password .
How to disable this feature ?

Share edited Sep 26, 2019 at 20:38 Seth 10.5k10 gold badges48 silver badges69 bronze badges asked Sep 26, 2019 at 20:31 mah454mah454 1,9501 gold badge21 silver badges49 bronze badges 3
  • Does the decrypt function return the same original value even if the crypted values are not equals? If so, what is the problem having different output? – Jonathan Larouche Commented Sep 26, 2019 at 20:59
  • 1 I need same hash . I do something like this in Java language and always return same hash . – mah454 Commented Sep 26, 2019 at 21:02
  • Even though I've provided a workaround/hack, I want to provide some security concern warnings . AES algorithm return different output for same input for a reason, Imagine you are encrypting password and many users are using identical password. Without the AES "ramdomness" then all identical password will have the same encrypted value. knowing one's password may reveal the other's. – Jonathan Larouche Commented Sep 27, 2019 at 15:16
Add a ment  | 

2 Answers 2

Reset to default 6

AES is designed to generated random output that are symmetrical (That can be decrypted)

CryptoJS AES uses Math.random() calls to generate a matrix/salt during cyphering and this randomness is included in the encrypted result, that's how decrypt can "uncypher" the encrypted data.

You can either fork the CryptoJS Library and replaces Math.random usage by your own seed or you can change the oute of Math.random at runtime for the duration of the encryption.

Thanks to Javascript, you can assign custom code to native function.

Here is Option #2. It will always return the same output, it uses the function fakeMathRandom. This will temporarily change the oute of Math.random for the duration of the callBack function

fakeMathRandom function

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;
}

Usage

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

Complete Demo Code:

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./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>

I hope that solve you problem!

We can generate same hash like this way using CryptoJS.

var CryptoJS = require("crypto-js");
let text='Rohit';
var key  = CryptoJS.enc.Hex.parse("27c69b41b5fe49aaa984e472d4aeaa5b");
var iv   = CryptoJS.enc.Hex.parse("17c69b41b5fe49aaa984e472d4aeaa5a");

var ciphertext = CryptoJS.AES.encrypt(text, key, {iv: iv}).toString();
console.log(ciphertext);

// Decrypt
var decryptStr  = CryptoJS.AES.decrypt(ciphertext, key, {iv: iv}).toString(CryptoJS.enc.Utf8);
console.log(decryptStr);
发布评论

评论列表(0)

  1. 暂无评论