Проблема HOTP: Node.js crypto.createHma c работает только когда счетчик равен 0 - PullRequest
0 голосов
/ 04 апреля 2020

Я пытаюсь создать одноразовый пароль на основе HMA C. Я следую rfc4226 (https://www.rfc-editor.org/rfc/rfc4226) спецификациям, но не могу заставить алгоритм работать, когда значения для count отличаются от 0. Что я делаю неправильно?

I Полагайте, что это как-то связано с тем, как я конвертирую значение счетчика: countBuffer.writeUInt32BE(count, 4);.

// The following text is copied from https://www.rfc-editor.org/rfc/rfc4226
// PAGE 32

// The following test data uses the ASCII string
// "12345678901234567890" for the secret:

// my note: Why above the secret is different than the one specified here?
// Secret = 0x3132333435363738393031323334353637383930

// Table 1 details for each count, the intermediate HMAC value.

// Count    Hexadecimal HMAC-SHA-1(secret, count)
// 0        cc93cf18508d94934c64b65d8ba7667fb7cde4b0
// 1        75a48a19d4cbe100644e8ac1397eea747a2d33ab
// 2        0bacb7fa082fef30782211938bc1c5e70416ff44
// 3        66c28227d03a2d5529262ff016a1e6ef76557ece
// 4        a904c900a64b35909874b33e61c5938a8e15ed1c
// 5        a37e783d7b7233c083d4f62926c7a25f238d0316
// 6        bc9cd28561042c83f219324d3c607256c03272ae
// 7        a4fb960c0bc06e1eabb804e5b397cdc4b45596fa
// 8        1b3c89f65e6c9e883012052823443f048b4332db
// 9        1637409809a679dc698207310c8c7fc07290d9e5

// Table 2 details for each count the truncated values (both in
// hexadecimal and decimal) and then the HOTP value.

//                   Truncated
// Count    Hexadecimal    Decimal        HOTP
// 0        4c93cf18       1284755224     755224
// 1        41397eea       1094287082     287082
// 2         82fef30        137359152     359152
// 3        66ef7655       1726969429     969429
// 4        61c5938a       1640338314     338314
// 5        33c083d4        868254676     254676
// 6        7256c032       1918287922     287922
// 7         4e5b397         82162583     162583
// 8        2823443f        673399871     399871
// 9        2679dc69        645520489     520489

const crypto = require("crypto");

const secret = "12345678901234567890"

// When I try to change count to any other number the
// results won't match the table above
// When using 0 the result matches the table above
const count = 0;

let countBuffer = Buffer.alloc(8, 0);
countBuffer.writeUInt32BE(count, 4);

const hmac_result = crypto.createHmac("sha1", secret)
  .update(countBuffer)
  .digest();

const offset = hmac_result[hmac_result - 1] & 0xf ;
const bin_code = (hmac_result[offset]  & 0x7f) << 24
    | (hmac_result[offset+1] & 0xff) << 16
    | (hmac_result[offset+2] & 0xff) <<  8
    | (hmac_result[offset+3] & 0xff) ;

let hotp = bin_code % (10 ** 6);

console.log(count, bin_code, hotp);

1 Ответ

0 голосов
/ 04 апреля 2020

После небольшой игры и сравнения моего кода с этим https://github.com/adalberht/hotp-totp-generator/blob/master/index.js мне удалось заставить его работать.

const crypto = require("crypto");

function generateHOTP(algorithm, secret, count, digits) {

  // Convert the string to binary data in the form of a sequence of bytes
  secret = Buffer.from(secret);

  // Writes value to buf at the specified offset with the specified endianness
  let countBuffer = Buffer.alloc(8, 0);
  countBuffer.writeUInt32BE(count, 4);

  // Creates and returns an Hmac object that uses the given algorithm and key
  const hmac_result = crypto.createHmac(algorithm, secret)
    .update(countBuffer)
    .digest("hex");

  // Chose the last byte of the hmac to do the dynamic truncation
  const offset = parseInt(hmac_result.charAt(hmac_result.length - 1), 16);

  // Dynamic truncation
  let hotp = parseInt(hmac_result.substr(offset * 2, 2 * 4), 16);
  hotp = hotp & 0x7fffffff;
  hotp = hotp.toString().padStart(digits, "0");

  return hotp;
}

for (let i = 0; i <= 9; i++) {
  console.log(i, generateHOTP("sha1", "12345678901234567890", i, 6));
}

Вывод соответствует усеченным десятичным значениям в таблице в вопрос:

0 '1284755224'
1 '1094287082'
2 '137359152'
3 '1726969429'
4 '1640338314'
5 '868254676'
6 '1918287922'
7 '82162583'
8 '673399871'
9 '645520489'
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...