Sage Pay / Opayo Form 集成 - 用 openssl 替换 mcrypt
Sage Pay / Opayo Form integration - replacing mcrypt with openssl
我们使用 Sage Pay / Opayo 表单集成将客户订单传递给 Sage Pay 进行付款,然后处理返回的报告。
Sage Pay 的示例代码依赖于 PHP mcrypt 函数,PHP 7.2 不再支持这些函数,因此我们需要将脚本更新为 OpenSSL。
这里有一篇很棒的 post 介绍了加密:
- 这对我来说很好用:
function encryptAes_new ($string, $key) {
$key = str_pad($key,16,"[=10=]"); # if supplied key is, or may be, less than 16 bytes
$crypt = openssl_encrypt($string, 'aes-128-cbc', $key, OPENSSL_RAW_DATA, $key);
// Perform hex encoding and return.
return "@" . strtoupper(bin2hex($crypt));
}
...但是我找不到匹配的代码来修复解密功能。
当前代码为:
function decryptAes($strIn, $password)
{
// HEX decoding then AES decryption, CBC blocking with PKCS5 padding.
// Use initialization vector (IV) set from $str_encryption_password.
$strInitVector = $password;
// Remove the first char which is @ to flag this is AES encrypted and HEX decoding.
$hex = substr($strIn, 1);
$strIn = pack('H*', $hex);
// Perform decryption with PHP's MCRYPT module.
$string = mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $password, $strIn, MCRYPT_MODE_CBC, $strInitVector);
return removePKCS5Padding($string);
}
有人可以帮忙提供 OpenSSL 版本吗?
解密时要先去掉@
前缀,然后进行16进制解码,最后才能解密。 openssl_decrypt()
隐式删除填充,因此不需要显式删除。这是在下面的 decryptAes_new()
中实现的:
<?php
function encryptAes_new ($string, $key) {
$key = str_pad($key,16,"[=10=]"); # if supplied key is, or may be, less than 16 bytes
$crypt = openssl_encrypt($string, 'aes-128-cbc', $key, OPENSSL_RAW_DATA, $key);
// Perform hex encoding and return.
return "@" . strtoupper(bin2hex($crypt));
}
function decryptAes_new($string, $key) {
$key = str_pad($key,16,"[=10=]");
$binary = hex2bin(substr($string, 1));
return openssl_decrypt($binary, 'aes-128-cbc', $key, OPENSSL_RAW_DATA, $key);
}
$plaintext = 'The quick brown fox jumps over the lazy dog';
$key = '0123456789012345';
$ciphertext = encryptAes_new($plaintext, $key);
$decrypted = decryptAes_new($ciphertext, $key);
print('Ciphertext: ' . $ciphertext . PHP_EOL);
print('Plaintext: ' . $decrypted . ' - Size: ' . strlen($decrypted) . PHP_EOL);
?>
产生输出:
Ciphertext: @3089E6BC224BD95B85CF56F4B967118AAA4705430F25B6B4D953188AD15DD78F3867577E7D58E18C9CB340647C8B4FD8
Plaintext: The quick brown fox jumps over the lazy dog - Size: 43
查看解密后的明文长度,43字节,说明padding已经自动去掉
Mike,谢谢你提出问题,谢谢 user16205441 的回答。
我发现答案适用于我的问题。
几个星期以来,我一直在尝试执行以下操作:
该字符串必须使用 AES(块大小 128 位)在 CBC 模式下使用 PKCS#5 填充进行加密。使用提供的密码作为密钥和初始化向量并将结果编码为十六进制(确保字母为大写)。
当我操作如下代码时:
<?php
function encryptAes_new ($string, $key) {
$key = str_pad($key,16,"[=10=]"); # if supplied key is, or may be, less than 16 bytes
$crypt = openssl_encrypt($string, 'aes-128-cbc', $key, OPENSSL_RAW_DATA, $key);
// Perform hex encoding and return.
return "@" . strtoupper(bin2hex($crypt));
}
function decryptAes_new($string, $key) {
$key = str_pad($key,16,"[=10=]");
$binary = hex2bin(substr($string, 1));
return openssl_decrypt($binary, 'aes-128-cbc', $key, OPENSSL_RAW_DATA, $key);
}
$plaintext = 'theLongStringIwasTryingToSend';
$key = 'abcdefghijklmnop';
$ciphertext = encryptAes_new($plaintext, $key);
$decrypted = decryptAes_new($ciphertext, $key);
print('Ciphertext: ' . $ciphertext . PHP_EOL);
print('Plaintext: ' . $decrypted . ' - Size: ' . strlen($decrypted) . PHP_EOL);
?>
它生成了 Opayo 团队所说的我的字符串应该生成的加密版本。
我有点惊讶,因为 Opayo 团队提到了用户 16205441 的回答没有明确提到的初始化向量 ($iv)。但如果它有效,这对我来说很重要。
我现在将再次尝试表单集成过程,看看团队怎么说!
祝一切顺利
NeverSayDai
我们使用 Sage Pay / Opayo 表单集成将客户订单传递给 Sage Pay 进行付款,然后处理返回的报告。 Sage Pay 的示例代码依赖于 PHP mcrypt 函数,PHP 7.2 不再支持这些函数,因此我们需要将脚本更新为 OpenSSL。
这里有一篇很棒的 post 介绍了加密:
- 这对我来说很好用:
function encryptAes_new ($string, $key) {
$key = str_pad($key,16,"[=10=]"); # if supplied key is, or may be, less than 16 bytes
$crypt = openssl_encrypt($string, 'aes-128-cbc', $key, OPENSSL_RAW_DATA, $key);
// Perform hex encoding and return.
return "@" . strtoupper(bin2hex($crypt));
}
...但是我找不到匹配的代码来修复解密功能。
当前代码为:
function decryptAes($strIn, $password)
{
// HEX decoding then AES decryption, CBC blocking with PKCS5 padding.
// Use initialization vector (IV) set from $str_encryption_password.
$strInitVector = $password;
// Remove the first char which is @ to flag this is AES encrypted and HEX decoding.
$hex = substr($strIn, 1);
$strIn = pack('H*', $hex);
// Perform decryption with PHP's MCRYPT module.
$string = mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $password, $strIn, MCRYPT_MODE_CBC, $strInitVector);
return removePKCS5Padding($string);
}
有人可以帮忙提供 OpenSSL 版本吗?
解密时要先去掉@
前缀,然后进行16进制解码,最后才能解密。 openssl_decrypt()
隐式删除填充,因此不需要显式删除。这是在下面的 decryptAes_new()
中实现的:
<?php
function encryptAes_new ($string, $key) {
$key = str_pad($key,16,"[=10=]"); # if supplied key is, or may be, less than 16 bytes
$crypt = openssl_encrypt($string, 'aes-128-cbc', $key, OPENSSL_RAW_DATA, $key);
// Perform hex encoding and return.
return "@" . strtoupper(bin2hex($crypt));
}
function decryptAes_new($string, $key) {
$key = str_pad($key,16,"[=10=]");
$binary = hex2bin(substr($string, 1));
return openssl_decrypt($binary, 'aes-128-cbc', $key, OPENSSL_RAW_DATA, $key);
}
$plaintext = 'The quick brown fox jumps over the lazy dog';
$key = '0123456789012345';
$ciphertext = encryptAes_new($plaintext, $key);
$decrypted = decryptAes_new($ciphertext, $key);
print('Ciphertext: ' . $ciphertext . PHP_EOL);
print('Plaintext: ' . $decrypted . ' - Size: ' . strlen($decrypted) . PHP_EOL);
?>
产生输出:
Ciphertext: @3089E6BC224BD95B85CF56F4B967118AAA4705430F25B6B4D953188AD15DD78F3867577E7D58E18C9CB340647C8B4FD8
Plaintext: The quick brown fox jumps over the lazy dog - Size: 43
查看解密后的明文长度,43字节,说明padding已经自动去掉
Mike,谢谢你提出问题,谢谢 user16205441 的回答。 我发现答案适用于我的问题。 几个星期以来,我一直在尝试执行以下操作: 该字符串必须使用 AES(块大小 128 位)在 CBC 模式下使用 PKCS#5 填充进行加密。使用提供的密码作为密钥和初始化向量并将结果编码为十六进制(确保字母为大写)。
当我操作如下代码时:
<?php
function encryptAes_new ($string, $key) {
$key = str_pad($key,16,"[=10=]"); # if supplied key is, or may be, less than 16 bytes
$crypt = openssl_encrypt($string, 'aes-128-cbc', $key, OPENSSL_RAW_DATA, $key);
// Perform hex encoding and return.
return "@" . strtoupper(bin2hex($crypt));
}
function decryptAes_new($string, $key) {
$key = str_pad($key,16,"[=10=]");
$binary = hex2bin(substr($string, 1));
return openssl_decrypt($binary, 'aes-128-cbc', $key, OPENSSL_RAW_DATA, $key);
}
$plaintext = 'theLongStringIwasTryingToSend';
$key = 'abcdefghijklmnop';
$ciphertext = encryptAes_new($plaintext, $key);
$decrypted = decryptAes_new($ciphertext, $key);
print('Ciphertext: ' . $ciphertext . PHP_EOL);
print('Plaintext: ' . $decrypted . ' - Size: ' . strlen($decrypted) . PHP_EOL);
?>
它生成了 Opayo 团队所说的我的字符串应该生成的加密版本。
我有点惊讶,因为 Opayo 团队提到了用户 16205441 的回答没有明确提到的初始化向量 ($iv)。但如果它有效,这对我来说很重要。
我现在将再次尝试表单集成过程,看看团队怎么说!
祝一切顺利
NeverSayDai