I've got the following code:
<script src="http://crypto-js.googlecode.com/svn/tags/3.1.2/build/rollups/aes.js"></script>
<div id="decrypted">Please wait...</div>
Insert new note:<input type="text" id="new_note"><input type="button" id="enc_button" value="Save">
<script>
var password = "testpassword";
var encrypted_text = localStorage.getItem("encrypted");
var rawData = atob(encrypted_text);
var iv = rawData.substring(0,16);
var crypttext = rawData.substring(16);
var plaintextArray = CryptoJS.AES.decrypt(
{ ciphertext: CryptoJS.enc.Latin1.parse(crypttext) },
CryptoJS.enc.Hex.parse(password),
{ iv: CryptoJS.enc.Latin1.parse(iv) }
);
var decrypted = CryptoJS.enc.Latin1.stringify(plaintextArray);
document.getElementById("decrypted").innerHTML = decrypted;
document.getElementById("enc_button").onclick = function(){
var text = document.getElementById("new_note").value;
var encrypted = CryptoJS.AES.encrypt(text, password);
localStorage.setItem("encrypted",encrypted);
}
</script>
Encrypt a string with AES using CryptoJS; decrypt encrypted text saved in local storage and show the result in a div
While the string seems to get encrypted, the variable decrypt
is empty. No errors are triggered in the chrome console.
How can I successfully encrypt and decrypt my text?
CryptoJS has two slightly different types of encryption/decryption.
When you use
var encrypted = CryptoJS.AES.encrypt(text, password);
then you're using password-based encryption which is not the same as pure key/IV-based encryption. This means that the password and a randomly generated salt are run through one MD5 invocation to produce the key and IV for the actual encryption. This is an OpenSSL compatible way to encrypt something. The encrypted
object stores the random salt which was used to generate the key and IV.
When you force encrypted
to be converted to string (like adding it to localStorage), then it is converted into an OpenSSL compatible string encoding which includes the salt. In order to decrypt it again, you don't need to mess around with the key, IV or salt yourself, because CryptoJS automatically does that for you:
var decrypted = CryptoJS.AES.decrypt(encrypted, password);
Keep in mind that decrypted
is a WordArray
object and when you force it to be converted to string it will encode the contents into Hex by default. If you don't want that then you need to specify the encoding such as UTF-8 yourself.
A blank value is usually returned when the decryption failed for some reason such as wrong key, wrong ciphertext or wrong encoding. CryptoJS won't throw custom error messages, but will try to continue, because you should know what you're doing.
Full code:
var password = "testpassword";
document.getElementById("enc_button").onclick = function(){
var text = document.getElementById("new_note").value;
var encrypted = CryptoJS.AES.encrypt(text, password);
encrypted = encrypted.toString();
var decrypted = CryptoJS.AES.decrypt(encrypted, password);
decrypted = decrypted.toString(CryptoJS.enc.Utf8)
document.getElementById("decrypted").innerHTML = decrypted;
}
<script src="https://cdn.rawgit.com/CryptoStore/crypto-js/3.1.2/build/rollups/aes.js"></script>
<div id="decrypted">Please wait...</div>
Insert new note:<input type="text" id="new_note"><input type="button" id="enc_button" value="Encrypt & Decrypt">
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With