简体   繁体   中英

Is there a way to decrypt a string which is encrypted in PBKDF2 format in javascript cryptoJS

Hi i was developing a password manager web app using normal html.I was storing the passwords in firebase firestore using client side encryption using cryptoJS and was currenty using aes for the same.I was also using firebase authentication and the secret phrase for the aes encryption is the uid provided by firebase the code looks something like this

  var user = firebase.auth().currentUser;
myPassword = user.uid+"QWERTYUIOPLKJHGASDFZXCVMNBqwertyuiopasdfghjklzxcvbnm1234567890!@#$)(*&^%-+=><,.:;{}[]"; 
encrypted = CryptoJS.AES.encrypt(document.getElementById("id").value, myPassword);

AND PBKDF2 encryption looks something like this

var salt = CryptoJS.lib.WordArray.random(128 / 8);var key512Bits1000Iterations = CryptoJS.PBKDF2("Secret Passphrase", salt, {keySize: 512 / 32,iterations: 1000});

can anyone tell how to decrypt the result we get after the above code ↑

A little on Password hashing

PBKDF2 is a password-based key derivation function, like bcrypt, scrypt, and Argon2 where Argon2 is was the winner of the 2015 password hashing competition (use Argon2id whenever possible). They used to derive keys from passwords. Then the question is

why do we need a special function for deriving a key from passwords instead of using just hash(password) ?

The answer relies on historical advancements. First, remember attacks always get better, they never get worse. The rainbow tables introduced by Philippe Oechslin

actually is was an extension of Merkle-Hellman's work and applied to real cases.

  • 1980 - Hellman, M. "A cryptanalytic time-memory trade-off

Rainbow tables

The Rainbow table is simply used to reverse any function, like encryption and hash function. When talking about the reverse on hash function one must be careful, here in this context it is just finding a pre-image x such that y=hash(x) for a given hash value y . Today, one can find many pre-built rainbow tables on the web.

What is the defense against the Rainbow tables? Using different salt per password. In this case, the Rainbow tables are useless. They need to be built for per salt and this is too costly. Therefore we can say using salt kills the Rainbows tables.

Massive GPU/ASIC/FPGA search

Though one can use CPUs for massive parallelization for password searching, too, using GPUs,ASIC/FPGA ( will use only word GPU on the rest) is much more effective since a CPU is a general processing unit, not a specialized one.

The attackers can use many GPU's altogether to search for the passwords. A good example is the hashcat. The attacker can use many instances in parallel to search for the password. This is just a parallel brute-force machine.

What are the countermeasures?

  • Iteration : you can increase the iteration. Consider that you use SHA for password hashing then the x -iteration is calling SHA x times SHA(SHA(...(SHA(x)...)) . This will slow you x times, however, they will slow the attacker x times, too.

    PBKDF2 takes iteration as a parameter to control this. One must be careful about the iteration count, you may not want your users to wait so much for the login. It is custom to adjust this value so that the user waits no more than one second. 100K, 250K, 500K, 1M iterations what we can see today. Consider that even you use 100K iteration, then you slowed the password searching 100K times, too.

  • Memory-Hard: In this case, the password hashing algorithms are using adjustable memory that cannot be contracted with a time-memory or similar technique so that they eliminate the massive searching, too. The GPUs don't have much memory to provide all threads so they are crippled heavily.

  • Parallelism : Argon2 uses a parallelization parameter, too. This also reduced the attacker's parallel running on CPUs, too.

back to your coding

myPassword = user.uid+"QWERTYUIOPLKJHGASDFZXCVMNBqwertyuiopasdfghjklzxcvbnm1234567890!@#$)(*&^%-+=><,.:;{}[]"; 
encrypted = CryptoJS.AES.encrypt(document.getElementById("id").value, myPassword);

When you use the CryptoJS encryption in this way it uses the non-standardized OpenSSL KDF for key derivation (EvpKDF) with MD5 as the hashing algorithm and 1 iteration.

While MD5 still secure against pre-images, it is fast for password hashing. Therefore you need to change it. You can use PBKDF2 with encryption as

function encrypt (msg, pass) {
  var salt = CryptoJS.lib.WordArray.random(128/8);
  
  var key = CryptoJS.PBKDF2(pass, salt, {
      keySize: keySize/32,
      iterations: iterations
    });

  var iv = CryptoJS.lib.WordArray.random(128/8);
  
  var encrypted = CryptoJS.AES.encrypt(msg, key, { 
    iv: iv, 
    padding: CryptoJS.pad.Pkcs7,
    mode: CryptoJS.mode.CBC
    
  });
  
  // salt, iv will be hex 32 in length
  // append them to the ciphertext for use  in decryption
  var transitmessage = salt.toString()+ iv.toString() + encrypted.toString();
  var encodeB4 = CryptoJS.enc.Base64.stringify(transitmessage);
  return encodeB4;
}

function decrypt (transitmessage, pass) {
  var decoded = const decoded = CryptoJS.enc.Utf8.stringify(transitmessage);

  var salt = CryptoJS.enc.Hex.parse(decoded.substr(0, 32));
  var iv = CryptoJS.enc.Hex.parse(decoded.substr(32, 32))
  var encrypted = decoded.substring(64);
  
  var key = CryptoJS.PBKDF2(pass, salt, {
      keySize: keySize/32,
      iterations: iterations
    });

  var decrypted = CryptoJS.AES.decrypt(encrypted, key, { 
    iv: iv, 
    padding: CryptoJS.pad.Pkcs7,
    mode: CryptoJS.mode.CBC
    
  })
  return decrypted;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM