Open OwenMelbz opened 6 years ago
Why not just check if decrypted == ""
and then print out your own exception/try again/whatever?
@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
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?
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!
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
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
ofbytes
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.
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
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?
Is there anyway to know that decryption failed? specifically with AES?
e.g if you put
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