Search code examples
javajavascriptcryptojs

CryptoJS.SHA1 vs MessageDigest.getInstance("SHA-1").digest()


i am trying to apply the SHA1 encryption in my javascript code, the same way that java work, the result as following : java :

String str = "123456";
MessageDigest sha = MessageDigest.getInstance("SHA-1");
byte[] hash = sha.digest(str.getBytes());
for(int i =0 ; i<hash.length;i++){
   System.out.print((new Byte(hash[i]))+" ");
}

the output for the java :

124 74 -115 9 -54 55 98 -81 97 -27 -107 32 -108 61 -62 100 -108 -8 -108 27

javascript :

var key = "123456";
console.warn(CryptoJS.SHA1(key.getBytes().toString()).toString().getBytes());

the outpur for javascript :

[54, 49, 52, 49, 51, 100, 55, 99, 53, 49, 50, 102, 100, 99, 98, 48, 98, 53, 53, 55, 57, 98, 55, 53, 56, 55, 50, 54, 53, 102, 55, 53, 99, 99, 98, 51, 53, 50, 52, 52]

How can I make the JavaScript work exactly how Java does it? So it also must produce an array.

String.prototype.getBytes = function () {
    var bytes = [];
    for (var i = 0; i < this.length; i++){
        bytes.push(this.charCodeAt(i));
    }
    return bytes;
};

Solution

  • I don't know what key.getBytes() is supposed to be. You should simply pass the string to the SHA1 function and get a representation of your choice out of it. This produces a matching hex representation of the byte array from your Java code.

    > var key = "123456";
    > CryptoJS.SHA1(key).toString()
    "7c4a8d09ca3762af61e59520943dc26494f8941b"
    

    If you want to create exactly the same array, you can iterate over the words property of the native representation of CryptoJS. Each integer represents 4 bytes in Big-Endian notation.

    var key = "123456";
    var hash = CryptoJS.SHA1(key);
    var byteArray = [];
    hash.words.forEach(function(i){ 
      var k;
      for(var j = 3; j >= 0; j--){
        k = (i >> (j*8)) & 0xFF;
        k = k < 128 ? k : -(256 - k);
        byteArray.push(k);
      }
    });