4

我们的 API 平台使用 CMAC-AES 哈希作为请求的签名。我们有可用于在 Java 和 .NET 中创建此哈希的库,但也需要为 PHP 找到解决方案。问题是我找不到任何似乎可靠地生成与在我们的服务器上或通过 Java/.NET 库生成的 CMAC 匹配的哈希的东西。

我发现的唯一库是 CryptLib,一个 alpha 库。

https://github.com/ircmaxell/PHP-CryptLib

但它没有生成相同的哈希,而且我对加密的理解还不够好(它强制 AES 的块大小为 16,当我在网上找到的说 AES 块大小为 128 时)。

我还有其他途径可以走吗?

4

1 回答 1

2

最终,上面的 PHP-CryptLib 库可以正常工作。我的问题只是我自己与二进制与十六进制数据有关的错误。

使用库一提供的测试数据

require_once 'lib/CryptLib/bootstrap.php'; 

$hasher = new CryptLib\MAC\Implementation\CMAC;

$key = '2b7e151628aed2a6abf7158809cf4f3c'; // from test/Data/Vectors/cmac-aes ...
$msg = '6bc1bee22e409f96e93d7e117393172a'; // from test/Data/Vectors/cmac-aes ...

$cmac = $hasher->generate($msg,$key); 

echo $cmac; 

// $cmac should be 070a16b46b4d4144f79bdd9dd04a287c
// actually getting ¢ nd{þ¯\ ¥á¼ÙWß­

除了 CMAC 散列器使用二进制数据而不是 ascii 字符,因此需要使用 pack() 对其进行打包:

$key = pack("H*", '2b7e151628aed2a6abf7158809cf4f3c');
$msg = pack("H*", '6bc1bee22e409f96e93d7e117393172a');

我具体的真实案例是尝试散列任意字符串,例如:

$msg = 'Client|Guid-023-23023-23|Guid-0230-2402-252|string|123456|2012-11-08T20:55:34Z';

为此,我需要一个这样的函数:

function pack_str($str) {        
    $out_str = ""; 
    $len = strlen($str); 
    for($i=0; $i<$len; $i++) { 
        $out_str .= pack("c", ord(substr($str, $i, 1))); 
    } 
    return $out_str; 
} 

一旦数据被该函数打包并通过散列器运行,我得到了我期望的 CMAC 散列。

于 2012-11-09T19:34:24.390 回答