brix / crypto-js

JavaScript library of crypto standards.
Other
15.9k stars 2.39k forks source link

[Question] Knowing when decryption failed? #158

Open OwenMelbz opened 6 years ago

OwenMelbz commented 6 years ago

Is there anyway to know that decryption failed? specifically with AES?

e.g if you put

var encrypted = CryptoJS.AES.encrypt('hello world', 'secret').toString();
var decrypted = CryptoJS.AES.decrypt(encrypted, 'not secret').toString()

then decrypted = ""

Is there anyway to force the decryption process to maybe throw an exception for example?


Update: Work around for others, we're for the time being storing a sha512 hash of the plain text before its encrypted, then once the decryption has finished, we take another sha512 of the result, and check if those hashes match to see if it was the original content. Not ideal but works currently

NuclearPhoenixx commented 6 years ago

Why not just check if decrypted == "" and then print out your own exception/try again/whatever?

OwenMelbz commented 6 years ago

@Phoenix1747 because if the thing you're encrypting - happens to be empty you don't know if it failed, or was just empty.

e.g imagine if you had a list of entries, each with "notes" field which needs to be encrypted as has something sensitive in it.

You don't know when opening one of the entries if the decryption failed (then need to tell the user to re-enter their secret)

or if they just have not entered any notes yet.

--

You would assume that if you do something like "toString" and it fails - it will return a failure, or at least a way to signify a failure.

if it returned false on failure so you could do like if decrypted !== false then you know it failed.

or typically otherwise it would throw an exception

Dante-101 commented 6 years ago

Well, it does fail but sporadically. On my system, I see it failing around 1 in 7 times with the error message - Malformed UTF-8 data.

I am unsure of what causes this flipping behaviour. Can someone explain?

haipengz commented 6 years ago

I don't know how to be aware of the decryption failure, but I notice that the return type CryptoJS.DecryptedMessage of AES.decrypt() has a .toString() method whose signature is:

toString(encoder?: CryptoJS.Encoder): string;

So, when decrypt you may need to pass a proper encoder to the .toString() method of the decrypted.

This works for me, and I haven't encounter any decryption failure yet:

import AES from 'crypto-js/aes'
import ENC from 'crypto-js/enc-utf8'

const SECRET_KEY = 'YOUR_SECRET_KEY'

const encrypt = (obj) => {
  const encrypted = AES.encrypt(JSON.stringify(obj), SECRET_KEY)

  return encrypted.toString()
}

const decrypt = (encryptedText) => {
  // Here use .toString(ENC) directly, not .toString(ENC.Utf8)
  const decryptedStr = AES.decrypt(encryptedText, SECRET_KEY).toString(ENC)

  try {
    return JSON.parse(decryptedStr)
  } catch (error) {
    return null
  }
}

export default {
  encrypt,
  decrypt,
}
...
const encrypted = encrypt('Hello world!')
const decrypted = decrypt(encrypted)  // Hello world!
timqian commented 6 years ago
const encrypted = CryptoJS.AES.encrypt('hello world', 'secret').toString();
const bytes = CryptoJS.AES.decrypt(encrypted, 'not secret');
console.log(bytes);

Result:

{ words: [ -875813749, 94714195, 1903581345, 2046233780 ],
  sigBytes: -164 }

sigBytes of bytes seems always negative when secret did not match.

It might be better if the lib can throw an error though

unssnu commented 5 years ago
const encrypted = CryptoJS.AES.encrypt('hello world', 'secret').toString();
const bytes = CryptoJS.AES.decrypt(encrypted, 'not secret');
console.log(bytes);

Result:

{ words: [ -875813749, 94714195, 1903581345, 2046233780 ],
  sigBytes: -164 }

sigBytes of bytes seems always negative when secret did not match.

It might be better if the lib can throw an error though

It's not work, I met positive when first try.

fannyhasbi commented 4 years ago

Sometimes it gives the correct string but not the actual value. I used toString(Crypto.enc.Utf8)

algo : Rabbit
message : 'hello'
secret : '123'
encrypted = 'U2FsdGVkX18DV/Lyte8IsaxBpnKm'

when I change the encrypted cipher expecting to be error or something but this is what I got and the decrypted message is still a valid string

cipher : 'U2FsdGVkX18DV/Lyte8IsaxBpnKm'
decrypted = '@J'

but when I change to this, it gives me error

cipher : U2FsdGVkX18DV/tesaxBpnKm
error : Error: Malformed UTF-8 data
tgwuyangyang commented 3 years ago

Sometimes it gives the correct string but not the actual value. I used toString(Crypto.enc.Utf8)

algo : Rabbit
message : 'hello'
secret : '123'
encrypted = 'U2FsdGVkX18DV/Lyte8IsaxBpnKm'

when I change the encrypted cipher expecting to be error or something but this is what I got and the decrypted message is still a valid string

cipher : 'U2FsdGVkX18DV/Lyte8IsaxBpnKm'
decrypted = '@J'

but when I change to this, it gives me error

cipher : U2FsdGVkX18DV/tesaxBpnKm
error : Error: Malformed UTF-8 data

i get same error, Have you solved it?