Search code examples
javascripthashcryptojs

Client-Side calculated MD5 hash using CryptoJS is differnt to terminal calculation


I have integrated a file upload into my web app. The file should not be uploaded but the MD5 hash of the file should be calculated on the client side and then only this hash should be sent to the server.

Javascript part:

if (input.files && input.files[0]) {
    let reader = new FileReader();
    reader.onload = (e) => {
       let data = e.target.result;      
       var hashed = CryptoJS.MD5(data);
       console.log('hashed: ' + hashed);
    }
    reader.readAsDataURL(input.files[0]);
}

However, the code above gives me different hash as terminal does (md5sum ).Terminal gives me the same hash as various online converters.

It is the same with SHA1 and SHA256 algorithms I tried.

Example: This image from Wikipedia gives the following hashes.

Terminal: e5d23cb99614778b2acb163b8ee90810

CryptoJS: 468641711626fcfe6d956ddb21ccd4c7


Solution

  • readAsDataURL() is going to return a base64 string (with a data URI preamble) so that's what your hashing however an MD5 terminal tool is just going to read the raw bytes & hash them as-is.

    To fix use:

    reader.readAsArrayBuffer(input.files[0]);
    

    to fetch the raw bytes and:

    var hashed = CryptoJS.MD5(CryptoJS.lib.WordArray.create(data));
    

    to pass them to CryptoJs in a format it can process.