如何使用 CryptoJS 通过 Javascript 实现 hmac SHA256
How to implement hmacSHA256 with Javascipt using CryptoJS
我们可以用CryptoJS.HmacSHA256(message, key)
计算一个hmac
但是我想用公式Sha256( concat ( key xor opad, Sha256( concat( key xor ipad, message ) )
来实现
我做了以下事情
const key = "e9058ab198f6908f702111b0c0fb5b36f99d00554521886c40e2891b349dc7a1";
const ipad = "3636363636363636363636363636363636363636363636363636363636363636";
const opad = "5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c";
const mess = "2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824";
const alpha = "b559d6edc4aaccd32c7d4dec9ca7076aa5c15c09197dd4301cbed54768c19bfd"; // key xor opad
const beta = "df33bc87aec0a6b946172786f6cd6d00cfab36637317be5a76d4bf2d02abf197"; // key xor ipad
const hmac = CryptoJS.SHA256( alpha + String ( CryptoJS.SHA256( ( beta + mess ) ) ) ) ;
但是它不起作用,有什么帮助吗?
例如,我发现下面的代码
hmac = "594b7b8b1dea8dd016c1702c5b2d8b75ba20d744423b08e8897f02454000abad"
但真正的是:"fc7e0b4417a84790035480f97f9a792d8328a497039ae483b4b85197c008669e"
它是用 CryptoJS.HmacSHA256(CryptoJS.enc.Hex.parse(mess), key))
计算的
参考实现 CryptoJS.HmacSHA256(CryptoJS.enc.Hex.parse(mess), key))
生成一个 HMAC using the SHA256 摘要。因此,消息被十六进制解码,密钥 UTF8 编码。 UTF8 编码产生一个 64 字节的密钥,正好是 SHA256 的块大小。因此,既不需要用 0x00 值填充到 64 字节,也不需要用 SHA256 散列。
在您的代码中,我的意思是看到以下问题:没有考虑不同的编码,这对结果至关重要。此外,在我看来,SHA256 的块大小没有被正确考虑或根本没有考虑。而异或运算,用CryptoJS就可以轻松完成,不需要其他工具
HMAC的计算可以分三步进行:
- 确定 (K xor opad) 和 (K xor ipad)。
- P=H((K xoripad)||M)的测定
- 确定HMAC = H( (K xor opad) || P ),对应最终结果
所有步骤都可以用 CryptoJS 完成。因此 crypto-js/src/hmac.js 是一个有用的蓝图。请注意,CryptoJS 在内部使用 WordArray
s。关于 XOR 操作,这意味着处理单词,即迭代 64/4 = 16 个单词。
一个可能的实现是:
// Key is UTF8 encoded 64 bytes -> no padding / no hashing required
const key = "e9058ab198f6908f702111b0c0fb5b36f99d00554521886c40e2891b349dc7a1"
const mess = "2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824";
// Step 1: determine K xor opad (oKeyWA), K xor ipad (iKeyWA)
//
var hasherBlockSizeBytes = 64; // in bytes
var hasherBlockSize = hasherBlockSizeBytes/4; // in words
var keyWA = CryptoJS.enc.Utf8.parse(key);
var oKeyWA = keyWA.clone();
var iKeyWA = keyWA.clone();
var oKeyWords = oKeyWA.words;
var iKeyWords = iKeyWA.words;
for (var i = 0; i < hasherBlockSize; i++) {
oKeyWords[i] ^= 0x5c5c5c5c;
iKeyWords[i] ^= 0x36363636;
}
// Step 2: determine P = H( (K xor ipad) || M )
//
var messWA = CryptoJS.enc.Hex.parse(mess);
var iKeyMessWA = iKeyWA.concat(messWA);
var iKeyMessHashWA = CryptoJS.SHA256(iKeyMessWA);
// Step 3: determine HMAC = H ( (K xor opad) || P)
//
var oKeyiKeyMessHashWA = oKeyWA.concat(iKeyMessHashWA);
var hmacWA = CryptoJS.SHA256(oKeyiKeyMessHashWA);
document.getElementById("hmac").innerHTML = hmacWA.toString(CryptoJS.enc.Hex);
// Comparison with built-in function
var hmacDirectWA = CryptoJS.HmacSHA256(messWA, keyWA);
document.getElementById("hmacDir").innerHTML = hmacDirectWA.toString(CryptoJS.enc.Hex);
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.1.1/crypto-js.min.js">
</script>
<p style="font-family:'Courier New', monospace;" id="hmac"></p>
<p style="font-family:'Courier New', monospace;" id="hmacDir"></p>
我们可以用CryptoJS.HmacSHA256(message, key)
但是我想用公式Sha256( concat ( key xor opad, Sha256( concat( key xor ipad, message ) )
我做了以下事情
const key = "e9058ab198f6908f702111b0c0fb5b36f99d00554521886c40e2891b349dc7a1";
const ipad = "3636363636363636363636363636363636363636363636363636363636363636";
const opad = "5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c";
const mess = "2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824";
const alpha = "b559d6edc4aaccd32c7d4dec9ca7076aa5c15c09197dd4301cbed54768c19bfd"; // key xor opad
const beta = "df33bc87aec0a6b946172786f6cd6d00cfab36637317be5a76d4bf2d02abf197"; // key xor ipad
const hmac = CryptoJS.SHA256( alpha + String ( CryptoJS.SHA256( ( beta + mess ) ) ) ) ;
但是它不起作用,有什么帮助吗?
例如,我发现下面的代码
hmac = "594b7b8b1dea8dd016c1702c5b2d8b75ba20d744423b08e8897f02454000abad"
但真正的是:"fc7e0b4417a84790035480f97f9a792d8328a497039ae483b4b85197c008669e"
它是用 CryptoJS.HmacSHA256(CryptoJS.enc.Hex.parse(mess), key))
参考实现 CryptoJS.HmacSHA256(CryptoJS.enc.Hex.parse(mess), key))
生成一个 HMAC using the SHA256 摘要。因此,消息被十六进制解码,密钥 UTF8 编码。 UTF8 编码产生一个 64 字节的密钥,正好是 SHA256 的块大小。因此,既不需要用 0x00 值填充到 64 字节,也不需要用 SHA256 散列。
在您的代码中,我的意思是看到以下问题:没有考虑不同的编码,这对结果至关重要。此外,在我看来,SHA256 的块大小没有被正确考虑或根本没有考虑。而异或运算,用CryptoJS就可以轻松完成,不需要其他工具
HMAC的计算可以分三步进行:
- 确定 (K xor opad) 和 (K xor ipad)。
- P=H((K xoripad)||M)的测定
- 确定HMAC = H( (K xor opad) || P ),对应最终结果
所有步骤都可以用 CryptoJS 完成。因此 crypto-js/src/hmac.js 是一个有用的蓝图。请注意,CryptoJS 在内部使用 WordArray
s。关于 XOR 操作,这意味着处理单词,即迭代 64/4 = 16 个单词。
一个可能的实现是:
// Key is UTF8 encoded 64 bytes -> no padding / no hashing required
const key = "e9058ab198f6908f702111b0c0fb5b36f99d00554521886c40e2891b349dc7a1"
const mess = "2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824";
// Step 1: determine K xor opad (oKeyWA), K xor ipad (iKeyWA)
//
var hasherBlockSizeBytes = 64; // in bytes
var hasherBlockSize = hasherBlockSizeBytes/4; // in words
var keyWA = CryptoJS.enc.Utf8.parse(key);
var oKeyWA = keyWA.clone();
var iKeyWA = keyWA.clone();
var oKeyWords = oKeyWA.words;
var iKeyWords = iKeyWA.words;
for (var i = 0; i < hasherBlockSize; i++) {
oKeyWords[i] ^= 0x5c5c5c5c;
iKeyWords[i] ^= 0x36363636;
}
// Step 2: determine P = H( (K xor ipad) || M )
//
var messWA = CryptoJS.enc.Hex.parse(mess);
var iKeyMessWA = iKeyWA.concat(messWA);
var iKeyMessHashWA = CryptoJS.SHA256(iKeyMessWA);
// Step 3: determine HMAC = H ( (K xor opad) || P)
//
var oKeyiKeyMessHashWA = oKeyWA.concat(iKeyMessHashWA);
var hmacWA = CryptoJS.SHA256(oKeyiKeyMessHashWA);
document.getElementById("hmac").innerHTML = hmacWA.toString(CryptoJS.enc.Hex);
// Comparison with built-in function
var hmacDirectWA = CryptoJS.HmacSHA256(messWA, keyWA);
document.getElementById("hmacDir").innerHTML = hmacDirectWA.toString(CryptoJS.enc.Hex);
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.1.1/crypto-js.min.js">
</script>
<p style="font-family:'Courier New', monospace;" id="hmac"></p>
<p style="font-family:'Courier New', monospace;" id="hmacDir"></p>