ColdFusion binaryDecode与php pack(H *)

时间:2018-10-09 09:29:06

标签: php coldfusion hmacsha1

我需要在ColdFusion中从40个字符的密钥中创建20个字符的可用密钥。是为了计算HMAC签名。

我正在呼叫的服务器使用php包(H *)函数验证签名。

当我尝试创建用于计算HMAC密封的密钥时,无法计算与PHP返回的密钥相同的密钥。 Pack(H *)返回20个字符,而CF(binaryDecode())返回18个字符,其中一些被忽略或结果不同。签名无效。

Ex:如果我尝试用这个来计算20个字符的密钥

  

“ 325A16A325127FD42B700D4810E83F6312877B92”:

     

PHP返回:2Z %% + p Hc?{   2Z%(+ pH)?c {。

$key = "325A16A325127FD42B700D4810E83F6312877B92";
$test = pack('H*',$key);
var_dump($test);

使用CF:

local.key   = toString(binaryDecode("325A16A325127FD42B700D4810E83F6312877B92", "hex"));
writeDump(local.key);

更多代码:

PHP。

function hmac_sha1 ($key, $data) {

    $length = 64; // block length for SHA1
    if (strlen($key) > $length) { $key = pack("H*",sha1($key)); }
    $key  = str_pad($key, $length, chr(0x00));
    $ipad = str_pad('', $length, chr(0x36));
    $opad = str_pad('', $length, chr(0x5c));
    $k_ipad = $key ^ $ipad ;
    $k_opad = $key ^ $opad;

    return sha1($k_opad  . pack("H*",sha1($k_ipad . $data)));


}
$key = "325A16A325127FD42B700D4810E83F6312877B92";
$validKey = pack('H*',$key);
$str = "7464052*08/10/2018:14:22:30*65.25EUR*AA123**3.0*FR*carmen*mail@gmail.com**********";
$sign = hmac_sha1($validKey, $str);
$test = pack('H*',$key);

返回: 23e7db20da9b58a47e27c151a65c2393a08ee4f5

local.key = toString(binaryDecode("325A16A325127FD42B700D4810E83F6312877B92","hex"));
local.crypto = createObject("miscellaneous.crypto").init();
local.str = "7464052*08/10/2018:14:22:30*65.25EUR*AA123**3.0*FR*carmen*mail@gmail.com**********";
local.sign = local.crypto.hmacSha1(local.key, local.str, "hex");

返回: ff8d510f348d1a9b3652b33b8e7780c9f8d4536e

1 个答案:

答案 0 :(得分:3)

问题在于如何传递十六进制密钥以及custom component如何在创建签名时使用它。 _getMacInstance()中的代码创建secretKeySpec,操纵提供的值-在这种情况下-产生完全不同的密钥。这就是签名不匹配的原因:

    var secretkeySpec = createObject( "java", "javax.crypto.spec.SecretKeySpec" ).init(
        toBinary( toBase64( key ) ), // Changes the key value
        javaCast( "string", algorithm )
    );

从技术上说,您可以通过消除所有转换并仅从十六进制解码密钥来使其工作:

    // Create the specification for our secret key.
    var secretkeySpec = createObject( "java", "javax.crypto.spec.SecretKeySpec" ).init(
        binaryDecode(arguments.key, "hex"), // Decodes raw HEX key
        javaCast( "string", algorithm )
    );

然后传入一个原始的十六进制密钥

crypto.hmacSha1("325A16A325127FD42B700D4810E83F6312877B92",value, "hex");

产生与PHP 23e7db20da9b58a47e27c151a65c2393a08ee4f5 相同的结果

但是,您可能需要修改组件处理键的方式。因此,它的脆性要小一些。例如,您可以使用arguments.encoding来修改hmac *函数以接受二进制,或者甚至支持不同的编码。一切都取决于您打算如何使用CFC。