2013-06-28 3 views
2

Я немного смущен. Я хочу получить байты строки, которая хешируется с SHA1.Разное в Java SHA1 vs JavaScript 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; 
} 

, который дает мне

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)); 

, который дает мне

[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Ó 

Первый выход равен JavaScript и Java, но второй отличается. Почему и как возможна контрольная сумма, например Úcûi®°<wkÒ>‘âÁË=ó5Ó?

ответ

1

Вот решение:

Javascript:

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

Выход: 2420e186fcdb8d0ea08d82fdfbfb8722d6cbf606

Java:

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

За исключением капитала против нижнего регистра, выход такой же. Кстати, это в шестнадцатеричном формате.

+0

Да, я понял это вчера. Проблема в Java - это байт, ограниченный (2^8). 128 - -128, 129 - -127 ... и 255 равно -1. В JavaScript нет этой «проблемы». – Niklas

2

В вашем JavaScript вы делаете SHA-1 на Строка которая является число от байта массива (так отличается от вашей строкиcontent).

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

В вашем Java, вы делаете SHA-1 на byte[] (что эквивалентно вашей Строкаcontent)

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

Ваш toString создающей очень разные данные к тому, что вы есть SHA-1-in in Java.

Кроме того (не уверен, если это уместно): внутренне, JavaScript использует UTF-16 для струнных.


Далее, вошедшего вывод вашего JavaScript не может быть SHA-1 как это неправильная длина; это вызвано .toString().getBytes(), повторенным на sha1 после того, как оно было рассчитано (Stephen C упоминает это в this comment).

+0

Проблема заключается в том CryptoJS.SHA1 поддерживает только строку. Я думал, было бы хорошо, если бы я просто преобразовал его в массив байтов, а затем в строку. – Niklas

+0

@ Никлас - Очевидно, нет !. Используйте другую библиотеку Javascript для вычисления хэшей! Или измените 'CryptoJS.SHA1 (content.getBytes(). ToString()). ToString(). GetBytes()' to 'CryptoJS.SHA1 (content) .toString(). GetBytes() –

+0

Я прокомментировал свою прототип функции toString и также попробовал оба вызова функций. Ни один из них не работает. – Niklas