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 ?
- 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 encryptingpassword
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
2 Answers
Reset to default 6AES
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);