Java SHA-1 для JavaScript с использованием CryptoJS - PullRequest
2 голосов
/ 23 октября 2019

У меня есть такой код для генерации пароля, написанного на Java

        MessageDigest messageDigestPassword = MessageDigest.getInstance("SHA1");
        messageDigestPassword .reset();
        byte[] password = "password".getBytes();
        messageDigestPassword .update(password);
        byte[] encryptedPassword = messageDigestPassword .digest();

        String date = "2019-10-22T11:33:13.393Z";
        byte[] dateBytes = date.getBytes(StandardCharsets.UTF_8);

        int offset = 0;
        byte[] outputBytes = new byte[dateBytes.length + encryptedPassword .length];
        System.arraycopy(dateBytes, 0, outputBytes, offset, dateBytes.length);
        offset += dateBytes.length;
        System.arraycopy(encryptedPassword , 0, outputBytes, offset, encryptedPassword .length);

        MessageDigest finalMessageDigeset = MessageDigest.getInstance("SHA-1");
        finalMessageDigeset.reset();
        finalMessageDigeset.update(outputBytes);
        byte[] finalPasswordBytes= finalMessageDigeset .digest();

        String finalBase64Password = new String(Base64.encode(finalPasswordBytes));

, и я пытаюсь переписать его на JavaScript, чтобы использовать его в почтальоне с - CryptoJS Пока у меня есть:

function wordArrayToByteArray(wordArray, length) {
if (wordArray.hasOwnProperty("sigBytes") && 
wordArray.hasOwnProperty("words")) {
    length = wordArray.sigBytes;
    wordArray = wordArray.words;
}

var result = [],
    bytes,
    i = 0;
while (length > 0) {
    bytes = wordToByteArray(wordArray[i], Math.min(4, length));
    length -= bytes.length;
    result.push(bytes);
    i++;
}
return [].concat.apply([], result);
}

function stringToBytes ( str ) {
var ch, st, re = [];
for (var i = 0; i < str.length; i++ ) {
ch = str.charCodeAt(i);  // get char 
st = [];                 // set up "stack"
do {
  st.push( ch & 0xFF );  // push byte to stack
  ch = ch >> 8;          // shift value down by 1 byte
}  
while ( ch );
// add stack contents to result
// done because chars have "wrong" endianness
re = re.concat( st.reverse() );
}
// return an array of bytes
return re;
}



var dateFixed = "2019-10-22T11:33:13.393Z";
var fixedDateBytes = stringToBytes(dateFixed);
var sha1Password= CryptoJS.SHA1("password");
console.log("sha1Password",sha1Password.toString(CryptoJS.enc.Hex));

var sha1PasswordBytes= wordArrayToByteArray(sha1Password, 20);

var concatedBytes= fixedDateBytes.concat(sha1PasswordBytes);

var finalShaPassWords= CryptoJS.SHA1(concatedBytes); 
console.log("finalShaPassWords",finalShaPassWords.toString(CryptoJS.enc.Hex));

console.log("finalShaPassWords",finalShaPassWords.toString(CryptoJS.enc.Base64));

Однако, к сожалению, представления Base64, написанные на этих двух языках, не совпадают.

Я проверил и байты с даты равны. Байты из хешированного пароля не являются. Таким образом, хеширование после concat не выполняется в JavaScript.

Я проверил хеширование первого пароля и сгенерировал байты, и они оба одинаковыеПоэтому моя строка предположения var sha1PasswordBytes= wordArrayToByteArray(sha1Password, 20); приводит к тому, что строка var finalShaPassWords= CryptoJS.SHA1(concatedBytes); возвращает неверное значение.

Может кто-нибудь подсказать, что не так? Может быть, это должно быть написано по-другому?

1 Ответ

1 голос
/ 23 октября 2019

Поскольку вы все равно используете CryptoJS, вы также можете использовать кодеры CryptoJS и WordArray#concat -метод , что значительно упрощает код:

var CryptoJS = require("crypto-js");

// Input
var inPwd = "password";
var inDate = "2019-10-22T11:33:13.393Z";

// Processing
var pwdHash = CryptoJS.SHA1(inPwd);                                         // hash and convert to WordArray
var date = CryptoJS.enc.Utf8.parse(inDate);                                 // convert to WordArray
var joinedData = date.clone().concat(pwdHash);                              // join date and hashed password
var joinedDataHash = CryptoJS.SHA1(joinedData);                             // hash joined data
var joinedDataHashB64 = CryptoJS.enc.Base64.stringify(joinedDataHash);      // convert to Base64 string

// Output
console.log("Result: " + joinedDataHashB64 );                              // Output: D235TBTZMfpSyB/CDl5MHAjH5fI=

Вывод этого кода совпадает с выводом Java-кода: D235TBTZMfpSyB/CDl5MHAjH5fI=

...