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

javascript - Why CryptoJS produced different value every time the browser loads - Stack Overflow

programmeradmin1浏览0评论

Following code is run on a web page via script tag. Every time I load the page or run the code in the browser console - I am getting different value...

var key = 'key-123:456';
var uid = 1234567890;
var encrypted = CryptoJS.AES.encrypt(id, key);
encrypted.toString();

How can I have single "encrypted value"for "single id" regardless of how many times I load the page or run the code in console?

Following code is run on a web page via script tag. Every time I load the page or run the code in the browser console - I am getting different value...

var key = 'key-123:456';
var uid = 1234567890;
var encrypted = CryptoJS.AES.encrypt(id, key);
encrypted.toString();

How can I have single "encrypted value"for "single id" regardless of how many times I load the page or run the code in console?

Share Improve this question asked Nov 2, 2017 at 19:12 wailerwailer 5517 silver badges22 bronze badges 7
  • 1 This encryption may use a salt that makes the value different everytime, to prevent stealing? Not sure though, just an idea. (like php and encryption) – DevMoutarde Commented Nov 2, 2017 at 19:17
  • 5 Because CryptoJS operates by default in CBC mode which uses a random initialization vector to achieve non-determinism. If you want a deterministic transformation then (1) that's usually not desirable property from your encryption to have and (2) you want ECB mode. Why do you want a deterministic transformation? See the relevant section of CryptoJS's README: github.com/jakubzapletal/crypto-js#block-modes-and-padding – apsillers Commented Nov 2, 2017 at 19:17
  • I agree with DevMoutarde. It is probably using time and some other factors to salt. – splitwire Commented Nov 2, 2017 at 19:19
  • I need to match the data downstream so I need to have a deterministic value to decrypt. Maybe I am not using CryptoJS correctly. I will look up your github doc now. – wailer Commented Nov 2, 2017 at 19:27
  • 1 @wailer Do you ever need to transform the data back to its original form? Could you use a hash instead? That would allow you to transform the data into a non-reversible form but would allow comparison in the hashed form. That's how secure password comparison works: you don't store the password but do store Hash(password), and when the user logs in you compare the hash to Hash(entry). Would that suit your needs, or do you need to decrypt the data at some point after the comparison? – apsillers Commented Nov 2, 2017 at 20:48
 |  Show 2 more comments

2 Answers 2

Reset to default 18

AES is a "block" cipher, which means it operates deterministically on fixed-length blocks from plaintext to ciphertext (and vice versa). However, it's typical (and generally preferred) to use a "mode of operation" that adds non-determinism to the encryption process. For example, CBC mode (which CryptoJS uses by default) XORs a random initialization vector with the plaintext before encrypting it (and, correspondingly, after decrypting it):

This is vastly preferred because otherwise an eavesdropper can detect duplicate blocks, which might allow an attacker to eventually understand what is being communicated -- undoing the entire point of your encryption.

However, it sounds like you want your encryption to have this specific weakness, which suggests to me that maybe you don't really want encryption at all. Instead, you might want a hash, which is a deterministic one-way transformation. (CryptoJS supports several hashes.) With a hash, a given input A will always hash to the same hash value H, so you can compare Hash(A) == Hash(B) to see if A == B. (This isn't a perfect comparison, since hashes have an infinite input space and finite output space, but hashes are deliberately designed so that it's very, very difficult to find two inputs that produce the same output.) This is how websites securely store your password: the service stores Hash(password) instead of password itself, then when a user submits a password entry, the sites compares Hash(entry) and Hash(password) to see if the entry is correct.

var hash = CryptoJS.SHA3(message);

However, if you really do need to reverse the transformed value back into plaintext and not just compare it to another hashed value, then you do need encryption. In that case, you can use the cryptographically inferior ECB mode, which has the weaknesses described above. In CryptoJS, you can do this by supplying an options object with a mode property:

CryptoJS.AES.encrypt(msg, key, { mode: CryptoJS.mode.ECB });

To make it simple, if you want to encrypt and decrypt to get same value without having funny characters and outputs around, use CryptoJS.AES.encrypt(msg, key, { mode: CryptoJS.mode.ECB });, passing in a third argument, although it is a weak approach, it's prolly the least you can hope for.

发布评论

评论列表(0)

  1. 暂无评论