ColdFusion binaryDecode 与 php pack(H*)
ColdFusion binaryDecode vs php pack(H*)
我需要在 ColdFusion 中从 40 个字符的密钥创建一个 20 个字符的可用密钥。就是计算一个HMAC签名。
我调用的服务器使用 php 包 (H *) 函数验证签名。
当我尝试创建密钥来计算 HMAC 密封时,我无法计算出与 PHP 返回的密钥相同的密钥。打包(H*)returns好20个字符,但是CF(binaryDecode()),returns18个,有的被忽略或者结果不一样。签名无效。
例如:如果我尝试用这个计算一个 20 个字符的密钥
"325A16A325127FD42B700D4810E83F6312877B92":
PHP return : 2Z�%�+p H�?c�{�, and with CF :
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);
Return: 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");
Return: ff8d510f348d1a9b3652b33b8e7780c9f8d4536e
问题在于您如何传递十六进制密钥以及 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
但是,您可能想要改为修改组件处理键的方式。所以它不那么脆。例如,您可以修改 hmac* 函数以接受二进制,甚至可能通过使用 arguments.encoding
支持不同的编码。一切都取决于您打算如何使用 CFC。
我需要在 ColdFusion 中从 40 个字符的密钥创建一个 20 个字符的可用密钥。就是计算一个HMAC签名。
我调用的服务器使用 php 包 (H *) 函数验证签名。
当我尝试创建密钥来计算 HMAC 密封时,我无法计算出与 PHP 返回的密钥相同的密钥。打包(H*)returns好20个字符,但是CF(binaryDecode()),returns18个,有的被忽略或者结果不一样。签名无效。
例如:如果我尝试用这个计算一个 20 个字符的密钥
"325A16A325127FD42B700D4810E83F6312877B92":
PHP return : 2Z�%�+p H�?c�{�, and with CF : 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);
Return: 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");
Return: ff8d510f348d1a9b3652b33b8e7780c9f8d4536e
问题在于您如何传递十六进制密钥以及 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
但是,您可能想要改为修改组件处理键的方式。所以它不那么脆。例如,您可以修改 hmac* 函数以接受二进制,甚至可能通过使用 arguments.encoding
支持不同的编码。一切都取决于您打算如何使用 CFC。