2

I am a little bit confused. I want to get the bytes of an String, which is hashed with SHA1.

JavaScript:

var content = "somestring";
console.warn(content.getBytes().toString());
console.warn(CryptoJS.SHA1(content.getBytes().toString()).toString().getBytes());

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

Array.prototype.toString = function(){
var result = "";
for(var i = 0; i < this.length; i++){
    result += this[i].toString();
}
return result;
}

which gives me

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

Java:

String message = "somestring";
byte[] sha1 = MessageDigest.getInstance("SHA1").digest(message.getBytes());
System.out.println(Arrays.toString(message.getBytes()));
System.out.println(Arrays.toString(sha1));
System.out.println(new String(sha1));

which gives me

[115, 111, 109, 101, 115, 116, 114, 105, 110, 103]
[-38, 99, -5, 105, -82, -80, 60, 119, 107, -46, 62, -111, -30, -63, -53, 61, -13, 1, 53, -45]
Úcûi®°<wkÒ>‘âÁË=ó5Ó

The first output is equal on JavaScript and Java, but the second is different. Why and how is a checksum like Úcûi®°<wkÒ>‘âÁË=ó5Ó possible?

4

3 回答 3

2

在您的JavaScript 中,您正在对String执行SHA-1 ,它是来自字节数组的数字(因此与您的String不同)。 content

console.warn(CryptoJS.SHA1(content.getBytes().toString()).toString().getBytes());
//                                              ^^

在您的Java中,您正在对 a 进行SHA -1byte[](相当于您的String content

byte[] sha1 = MessageDigest.getInstance("SHA1").digest(message.getBytes());
//                                                                ^^

toString正在创建与您在Java中使用SHA-1的数据非常不同的数据。

另外(不确定是否相关):在内部,JavaScriptStrings使用UTF-16


此外,JavaScript的日志输出不能是SHA-1,因为它的长度错误;这是由于在计算后.toString().getBytes()重复sha1Stephen C在此评论中提到了这一点)。

于 2013-06-28T00:40:21.757 回答
1

这是解决方案:

Javascript:

key = 'testKey';
var hashedKey = CryptoJS.SHA1(key);
console.log(hashedKey);

输出:2420e186fcdb8d0ea08d82fdfbfb8722d6cbf606

爪哇:

password="testKey";
final MessageDigest md = MessageDigest.getInstance("SHA1");
ByteArrayOutputStream pwsalt = new ByteArrayOutputStream();
pwsalt.write(password.getBytes("UTF-8"));
byte[] unhashedBytes = pwsalt.toByteArray();
byte[] digestVonPassword = md.digest(unhashedBytes);
System.out.println(bytesToHex(digestVonPassword));

输出:2420E186FCDB8D0EA08D82FDFBFB8722D6CBF606

除了大写字母和小写字母之外,输出是相同的。顺便说一句,它是十六进制的。

于 2013-06-28T13:01:46.687 回答
0

我找到了这个图书馆。它产生与 Java 相同的值

https://caligatio.github.io/jsSHA/

于 2016-10-27T12:08:19.080 回答