Search code examples
javascripthtmlvue.jsfile-uploadcryptojs

File in selected file array md5 encryption with CryptoJS always gives the same md5 value


In my Vuejs front-end, there is a file upload button. When user selected the file Vuejs triggers the @change event.I have used the file reader and I have imported the Cryptojs libraries which I have downloaded as node modules(in npm).

import cryptoJs from '../../node_modules/crypto-js'
import md5 from '../../node_modules/crypto-js/md5'

My html code for file upload button as follows:

<input type="file" ref="uploadedfile" name="file1" id="file1" @change="handleFileUpload">

File reader code inside the @change function:

handleFileUpload(e){

const filesToRead = e.target.files;
//getting the first file from the files array
let file1 = filesToRead[0];

const fileReader = new FileReader();

fileReader.addEventListener('loadend', (evt) => {

      if (evt.target.readyState == FileReader.DONE) {
        file1 = fileReader.result;
        const encryptedvalue = md5(cryptoJs.enc.Latin1.parse(file1)).toString();
        console.log("MD5 value is :");
        console.log(encryptedvalue);
      }
      
    });
}

But always I get the same md5 value although I selected different files.

In the file object array, I can see all the file related data also when I inspect through the Chrome developer tool's console.(If I console log as follows)

console.log(file1);

Solution

  • The posted code lacks the call that loads the data. This is probably just a copy/paste error. Since the data is parsed with the Latin1 (aka ISO 8859-1) encoder, FileReader.readAsBinaryString() is an appropriate method, e.g.:

    handleFileUpload(e) {
      const filesToRead = e.target.files;
      let file1 = filesToRead[0];
      const fileReader = new FileReader();
      fileReader.addEventListener('loadend', (evt) => {
        if (evt.target.readyState == FileReader.DONE) {
          file1 = fileReader.result;
          const encryptedvalue = md5(cryptoJs.enc.Latin1.parse(file1)).toString();
          console.log("MD5 value is :");
          console.log(encryptedvalue);
        }      
      });
      fileReader.readAsBinaryString(file1); // missing in the posted code
    }
    

    However, I cannot reproduce the problem with this code, neither locally nor online https://codesandbox.io/s/brave-fast-cx9gz (if in the online case the error message C is undefined is displayed, this can generally be eliminated by commenting out and in the two CryptoJS import lines in components/Repro - no idea why this happens).


    However, I can reproduce the issue when the data is loaded with FileReader.readAsArrayBuffer(). If the ArrayBuffer is then parsed with the Latin1 encoder (as in the posted code), which is incompatible for this, then for different files always the same hash results. The result is correct again if the WordArray is created directly from the ArrayBuffer with:

    const encryptedvalue = md5(cryptoJs.lib.WordArray.create(file1)).toString();