Преобразование 64-битной числовой строки в массив слов с использованием CryptoJS

Я хочу знать, можно ли правильно преобразовать строку с целочисленными данными в массив слов CryptoJS? Пример. Могу ли я преобразовать «175950736337895418» в массив слов так же, как я могу создать массив слов из 175950736337895418 (значение int).

У меня есть код, который преобразует целые значения в массив слов

 // Converts integer to byte array
 function getInt64Bytes( x ){
    var bytes = [];
    for(var i = 7;i>=0;i--){
        bytes[i] = x & 0xff;
        x = x>>8;
    }
    return bytes;
}

//converts the byte array to hex string
function bytesToHexStr(bytes) {
    for (var hex = [], i = 0; i < bytes.length; i++) {
        hex.push((bytes[i] >>> 4).toString(16));
        hex.push((bytes[i] & 0xF).toString(16));
    }
    return hex.join("");
}

// Main function to convert integer values to word array
function intToWords(counter){
    var bytes = getInt64Bytes(counter);
    var hexstr = bytesToHexStr(bytes);
    var words = CryptoJS.enc.Hex.parse(hexstr);
    return words;
}

Даже этот код не работает правильно, так как очень большие целые числа (превышающие ограничение javascript на числа 2 ^ 53 - 1) округляются. Следовательно, мне нужно решение, которое могло бы принимать целочисленное значение в виде строки и правильно преобразовывать его в массив слов.

PS. Мне нужен этот массив слов для вычисления значения HMAC, используя следующий код

CryptoJS.HmacSHA512(intToWords(counter), CryptoJS.enc.Hex.parse(key))

person grane2212    schedule 05.08.2015    source источник


Ответы (1)


Что вы хотите, так это анализировать большие числа из строк. Поскольку это необходимо для RSA, вы можете использовать JSBN Тома Ву, чтобы получить эту функциональность. Обязательно включите jsbn.js и jsbn2.js. Затем вы можете использовать его следующим образом:

function intToWords(num, lengthInBytes) {
    var bigInt = new BigInteger();
    bigInt.fromString(num, 10); // radix is 10
    var hexNum = bigInt.toString(16); // radix is 16
    
    if (lengthInBytes && lengthInBytes * 2 >= hexNum.length) {
        hexNum = Array(lengthInBytes * 2 - hexNum.length + 1).join("0") + hexNum;
    }

    return CryptoJS.enc.Hex.parse(hexNum);
}

var num = "175950736337895418";
numWords = intToWords(num);

document.querySelector("#hexInt").innerHTML = "hexNum: " + numWords.toString();
document.querySelector("#hexIntShort").innerHTML = "hexNumShort: " + intToWords("15646513", 8).toString();

var key = CryptoJS.enc.Hex.parse("11223344ff");

document.querySelector("#result").innerHTML = "hexHMAC: " + 
        CryptoJS.HmacSHA512(numWords, key).toString();
<script src="https://cdn.rawgit.com/jasondavies/jsbn/master/jsbn.js"></script>
<script src="https://cdn.rawgit.com/jasondavies/jsbn/master/jsbn2.js"></script>
<script src="https://cdn.rawgit.com/CryptoStore/crypto-js/3.1.2/build/rollups/hmac-sha512.js"></script>
<div id="hexInt"></div>
<div id="hexIntShort"></div>
<div id="result"></div>

Если вам нужен результат определенной длины, вы можете передать количество необходимых байтов в качестве второго аргумента.

person Artjom B.    schedule 06.08.2015
comment
Фрагмент кода работает для вас? Я не вижу результатов! - person grane2212; 06.08.2015
comment
Да, это работает. Добавьте необходимые правила Noscript XSS. - person Artjom B.; 06.08.2015
comment
Код работает нормально! Есть одна проблема, которую я пытаюсь выяснить. Код, который у меня есть, создает 8-байтовое шестнадцатеричное значение (с нулями в начале), но ваш код дает мне точное шестнадцатеричное значение. Знаете ли вы, как я могу получить отступ перед шестнадцатеричным значением. Например, если я передам 15646513 функции intToWords, я получу eebf31 из вашей функции и 0000000000eebf31 из своей функции. Мне нужно убедиться, что я получил дополнение, так как я испорчу свои дальнейшие вычисления. - person grane2212; 06.08.2015
comment
Я расширил его, используя конкатенацию строк 0 в шестнадцатеричном формате. - person Artjom B.; 06.08.2015
comment
Если это решило вашу проблему, вы можете принять этот ответ. Пожалуйста, посмотрите на свой старый вопрос, чтобы увидеть, можете ли вы принять его ответ. Кроме того, вы также можете голосовать за сообщения, если вы нашли их полезными (или нет). - person Artjom B.; 06.08.2015
comment
Я заметил, что если значение счетчика отрицательное, то bigInt неправильно преобразуется в шестнадцатеричное значение. Я пытался установить значение счетчика как -52, и в этом случае BigInt преобразует его в -34 (что в идеале должно быть FFFFFFFFFFFFFFCC). Не могли бы вы помочь мне понять, что может быть не так? - person grane2212; 10.08.2015
comment
Вы можете задать другой вопрос и на этот раз полностью указать свои требования. Не забудьте включить то, что вы пробовали, чтобы не допустить, чтобы это было закрыто как слишком широкое. - person Artjom B.; 10.08.2015