0

我正在尝试使用 javascript 解码 Firefox Sync 数据,并移植一个执行此操作的 php 库(https://github.com/mikerowehl/firefox-sync-client-php)。这个想法是在不向服务器发送同步密钥的情况下解码同步数据。这只是上下文,我遇到的问题要具体得多。

一部分代码需要使用sha256来获取某个key。我想用javascript复制它。我用 CryptoJS 尝试过的方法是这样的:

PHP代码:

$key = hash_hmac("sha256",'OLA K ASE','CLAVE', false);
print $key;

等效的 Javascript 代码(以前,我已包含http://crypto-js.googlecode.com/svn/tags/3.1.2/build/rollups/hmac-sha256.js):

var hash = CryptoJS.HmacSHA256("OLA K ASE", "CLAVE");
console.log(hash.toString());

这工作正常。在每种情况下,输出都是 9591d44df0c8e2d7a1f400f41117c536e10f58d7e28bdc1cad9d81e70290bc1b,我认为这是正确的。

但是,当我尝试对非 ascii 字符串进行编码时,结果会有所不同。例如,使用这个 PHP 代码:

function hexstring($str){
    return preg_replace('/\\\\x([0-9a-f]{2})/e', 'chr(hexdec(\'$1\'))', $str);
}
$text = hexstring('\x00\x44\xb0\x2c\x0b');
$key = hexstring('\xd6\xf8\xb0\x2c\x0b');
$hash = hash_hmac("sha256",$text,$key, false);
print $hash;

我明白了0697f5528c996006ffeb09b9130bf8e9056563245656d405e233bcafdbffb645。但是使用“等效”的 javascript 代码:

var text = "\x00\x44\xb0\x2c\x0b";
var key = "\xd6\xf8\xb0\x2c\x0b";
hash = CryptoJS.HmacSHA256(text,key);
console.log(hash.toString());

我明白13c983b69f82c277815c03d13e90b1ec1e9cbca2b6912ad1f8224f3de8b82130了,不同的价值。

我认为这可能是由非ASCII字符引起的,所以我做了一个快速测试:

$text = '';
for($i = 0;$i < 10; $i++){
    $text .= chr($i);
}
$key = '';
for($i = 0;$i < 10; $i++){
    $key .= chr($i*2);
}
$hash = hash_hmac("sha256",$text,$key, false);
print $hash;

并且,javascript 等价物:

var text = '';
for(i = 0;i < 10; i++){
    text += String.fromCharCode(i);
}
var key = '';
for(i = 0;i < 10; i++){
    key += String.fromCharCode(i*2);
}
var hash = CryptoJS.HmacSHA256(text, key);
console.log(hash.toString());

在这两种情况下,输出都是c5d7adbbabcec5416c6b7a1f01e17e42d95a529f5bcc805d9b04b93f33994c9d

这是一个很大的WTF?为了我。有人可以给我一个关于如何继续这个的建议吗?

4

2 回答 2

2

解决了。这是字符代码的问题。而不是这个:

var text = "\x00\x44\xb0\x2c\x0b";
var key = "\xd6\xf8\xb0\x2c\x0b";
hash = CryptoJS.HmacSHA256(text,key);

我应该指出 CryptoJS 它们是 Latin-1 编码的字符串:

var text = CryptoJS.enc.Latin1.parse("\x00\x44\xb0\x2c\x0b");
var key = CryptoJS.enc.Latin1.parse("\xd6\xf8\xb0\x2c\x0b");
hash = CryptoJS.HmacSHA256(text,key);

我不清楚为什么会发生这种情况,所以如果有人可以用一点细节来解释它会很棒。

于 2013-12-07T20:55:03.850 回答
0

试试看:

$text = "\x00\x44\xb0\x2c\x0b";
$key = "\xd6\xf8\xb0\x2c\x0b";
$hash = hash_hmac("sha256",$text,$key, false);
print $hash;

可能是因为 preg_* 函数对这些特殊字符有问题。PHP 支持 \x12 十六进制编码,没有任何功能。

于 2013-12-06T21:03:37.573 回答