Search code examples
cryptojs

SHA-256 hash computed by CryptoJS is different


I am developing a website that has an upload feature.

In the frontend the I used Javascript library CryptoJS to calculate the SHA-256 hash from the file content and send it along with the file to the server.

function onMyfileChange(fileInput) {
    if(fileInput.files[0] == undefined) {
        return ;
    }
    var filename = fileInput.files[0].name;
    var reader = new FileReader();
    reader.onload = function(ev) {
        var fileContent = ev.target.result;
        var sha256hash = CryptoJS.SHA256(fileContent).toString(CryptoJS.enc.Hex);
        // do something with the hash
    };
    reader.onerror = function(err) {
        console.error("Failed to read file", err);
    }
    reader.readAsArrayBuffer(fileInput.files[0]);
}

In the backend server I use Java to calculate the SHA-256 hash from the file content again and compare it with the SHA-256 hash sent from the server to check the integrity of the file.

import org.apache.commons.codec.digest.DigestUtils;

byte[] data = ...

String sha256hash = DigestUtils.sha256Hex(data);

The problem is the SHA-256 hash calculated by CryptoJS is different than the one calculated by Java.

To crosscheck I use an online tool to verify the SHA-256 hash from the same file.

sha256

I also developed a tool written in C# to calculate the SHA-256 hash.

var fileContent = File.ReadAllBytes(fileName);

var sha = SHA256.Create();
byte[] checksum = sha.ComputeHash(fileContent);
var sha256 = BitConverter.ToString(checksum).Replace("-", String.Empty);
Console.WriteLine(sha256.ToString());

The SHA-256 hash calculated by Java is the same as the one generated by the online tool and the C# tool I wrote so there must be something wrong with the way I am using CryptoJS.


Solution

  • Instead of passing the array buffer to the CryptoJS.SHA256 I need to convert it to WordArray first.

    var fileContent = ev.target.result;
    var wa = CryptoJS.lib.WordArray.create(fileContent);
    var sha256hash = CryptoJS.SHA256(wa).toString(CryptoJS.enc.Hex);