I've been trying to decrypt an ArrayBuffer object using CryptoJS, but so far it always returns a blank WordArray. The files (images) are encrypted in an iOS and Android app, sent to a server, and downloaded in this web app to be decrypted and displayed. The iOS and Android apps are able to decrypt the files without problems, so there's nothing wrong with the encryption process.
The files are downloaded with an XMLHttpRequest
with responseType
set to arraybuffer
. Here's my code so far:
// Decrypt a Base64 encrypted string (this works perfectly)
String.prototype.aesDecrypt = function(key) {
var nkey = CryptoJS.enc.Hex.parse(key.sha256());
return CryptoJS.AES.decrypt(this.toString(), nkey, {
iv: CryptoJS.enc.Hex.parse('00000000000000000000000000000000'),
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.Pkcs7
}).toString(CryptoJS.enc.Utf8);
}
// Decrypt a plain encrypted ArrayBuffer (this is the problem, it always outputs an empty WordArray)
ArrayBuffer.prototype.aesDecrypt = function(key) {
// Get key
if (!key) return null;
var nkey = CryptoJS.enc.Hex.parse(key.sha256());
// Get input (if I pass the ArrayBuffer directly to the create function, it returns
// a WordList with sigBytes set to NaN)
//var input = CryptoJS.lib.WordArray.create(this);
var input = CryptoJS.lib.WordArray.create(new Uint8Array(this));
// Decrypt
var output = CryptoJS.AES.decrypt(input, nkey, {
iv: CryptoJS.enc.Hex.parse('00000000000000000000000000000000'),
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.Pkcs7
});
// Output is an empty WordList
console.log("Output: ", output);
}
Another question I have is how do you convert a WordArray
to an ArrayBuffer
?
ArrayBuffer is known as the basic binary object. It is a reference to a fixed-length contiguous memory area. ArrayBuffer can be generated in the following way: let buffer = new ArrayBuffer ( 16 ); // create a buffer of length 16 console .log (buffer.byteLength); // 16. Javascript ArrayBuffer is the raw binary data.
You can also get an array buffer from existing data, for example, from a Base64 string or from a local file. Creates a new ArrayBuffer object. The constructor function that is used to create derived objects.
The same methods and properties are used by them. There is no constructor TypedArray. It’s just an “umbrella” term for representing one of the views over ArrayBuffer. For example, new new TypedArray means one of the new Int8Array, new Uint8Array, and more. The Typed array is similar to the regular arrays: they include iterable and indexes.
If you've encrypted your files with EFS, then you can easily decrypt them from the Properties section. Right-click on the encrypted file and select Properties. In the General tab, select Advanced.
The conversion of ArrayBuffer -> WordArray
has been discussed in CryptoJS's issue 46. For that reason a TypedWordArray
where you can also pass an ArrayBuffer
has been added.
To use that additionally include the following script:
<script src="http://crypto-js.googlecode.com/svn/tags/3.1/build/components/lib-typedarrays.js"></script>
Then you can simply do:
var wordArray = CryptoJS.lib.WordArray.create(arrayBuffer);
/* perform decryption of `wordArray` */
To reconvert the resulting decryptedWordArray
to an ArrayBuffer
, the simplest approach would probably be, to first convert it to a Base64-String
(as discussed here) and then decode that String to the desired ArrayBuffer
(see here). The whole procedure would look something like this:
dcWordArray = ... // your decrypted WordArray
dcBase64String = dcWordArray.toString(CryptoJS.enc.Base64); // to Base64-String
dcArrayBuffer = base64DecToArr(dcBase64String).buffer; // to ArrayBuffer
Edit:
For a more efficient conversion (no intermediate Base64String
necessary) check out Aletheios answer to that question (the function wordToByteArray(wordArray)
and then do .buffer
).
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