HmacSHA1在Node crypto和CryptoJS中的结果不同

问题描述 投票:0回答:1

我从this implementation开始在NativeScript应用中使用Google Authenticator实现两要素身份验证。由于Node的加密模块未在NativeScript中运行,因此我试图使其与CryptoJS一起使用。

这是有效的Node代码。该函数返回具有正确值的缓冲区。

const crypto = require('crypto');

function generateHOTP(secret, counter) {
    const buffer = Buffer.alloc(8);
    for (let i = 0; i < 8; i++) {
       buffer[7 - i] = counter & 0xff;
       counter = counter >> 8;
    }

    const hmac = crypto.createHmac('sha1', secret);
    hmac.update(buffer);
    return hmac.digest();
}

这是CryptoJS等效项。返回的值与先前的函数不同,有时无论输入多少,多次迭代都返回相同的值。

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

function generateHOTP(secret, counter) {
    const buffer = Buffer.alloc(8);
    for (let i = 0; i < 8; i++) {
       buffer[7 - i] = counter & 0xff;
       counter = counter >> 8;
    }

    let result = CryptoJS.HmacSHA1(buffer.toString(), secret); // buffer.toString() is the problem
    return Buffer.from(result.toString(), "hex");
}

如果在第一个函数中将hmac.update(buffer)更改为hmac.update(buffer.toString()),它将返回与第二个相同的错误值,因此问题出在此字符串转换中。 buffer是一个UInt8Array。

如何固定CryptoJS.HmacSHA1(message, key)的第一个参数以返回与第一个函数相同的值?

node.js nativescript cryptojs
1个回答
0
投票

[您正在为密码模块提供缓冲区,而您正在向CryptoJS提供字符串。可能它们处理的字符串与缓冲区不同。 CryptoJS不支持将Buffer作为输入,仅支持字符串和WordArray,因此窍门是将Buffer转换为WordArray:

更改以下行:

let result = CryptoJS.HmacSHA1(buffer.toString(), secret);

至:

let result = CryptoJS.HmacSHA1(CryptoJS.lib.WordArray.create(buffer), secret);

如果您希望代码更符合加密版本(CryptoJS具有相似的接口):

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

function generateHOTP(secret, counter) {
    const buffer = Buffer.alloc(8);
    for (let i = 0; i < 8; i++) {
        buffer[7 - i] = counter & 0xff;
        counter = counter >> 8;
    }

    const hmac = CryptoJS.algo.HMAC.create(CryptoJS.algo.SHA1, secret);
    hmac.update(CryptoJS.lib.WordArray.create(buffer))
    return Buffer.from(hmac.finalize().toString(), 'hex');
}
© www.soinside.com 2019 - 2024. All rights reserved.