最近在做建行的 B2B 支付接口(B2C和B2B差不多)
支付成功后接收银行通知并验签出现的问题和解决方案,现在一一记下:
建行提供的验签DEMO php版的是用 COM 组件 但是我的服务器是LINUX 的对COM组件不支持(听说网上有方法支持,太烦放弃)。
还有种方法是用PHP 调用 JAVA 的类 (PHP-Java-Bridge方法 这个这里不说自己百度)
这里详细说下用 PHP 的openssl_verify 来验签, 各位看官 请随我慢慢道来
下面是步骤:
1.openssl_verify 需要一个PEM格式的公钥 从建行下载一个公钥(建行提供的一个公钥是一串 字符串 并且是16进制的,并且 你每次下载的公钥是不同的 是会变的哦 这个注意 )
2.想办法把这串 16进制的公钥转成PEM 格式于是百度发现没有具体的方案。现在给出php代码 通过下面的代码即可转成PEM格式
function der2pem($der_data)
{
$pem = chunk_split(base64_encode(hex2bin($der_data)), 64, “\n”);
$pem = “—–BEGIN PUBLIC KEY—–\n” . $pem . “—–END PUBLIC KEY—–\n”;
return $pem;
}
调用方法:der2pem(‘公钥串’);
3.验签(php代码如下)
/**
* 验证签名
* @param array $val 原字符串
* @param type $sign 加密串
*/
public function verifySign($val, $sign)
{
$data = ”;
foreach ($val as $k => $v)
{
if(\Org\Util\String::is UTF8 ($v)) //判断 编码 UTF8 需要转换下
{
$data.=iconv(‘utf-8’, ‘ GBK ‘, $v);
}
else
{
$data.=$v;
}
}
$public_key = self::PUBKEY;
$public_key = file_get_contents(dirname(__FILE__ ) . ‘/’ . $public_key);
$pkeyid = openssl_get_publickey($public_key);
$verifyResult = openssl_verify($data, pack(“H” . strlen ($sign), $sign), $pkeyid, OPENSSL_ALGO_MD5);
openssl_free_key($pkeyid);
return $verifyResult == 1 ? true : false;
}
4.特别说明:
a.建行的加密参数是GBK的所以验签的时候的UTF8的编码要转GBK的
b.建行页面通知get参数中文居然没有 URL编码 所有在ie下可能是乱码 (用THINKPHP 框架的用I方法会获取不到含中文的参数 所以要用原生的$_GET方法)
c.openssl_verify($data, pack(“H” . strlen($sign),
$sign), $pkeyid, OPENSSL_ALGO_MD5);
//建行是采用的rsawithmd5的加密方法所有验签时要用到OPENSSL_ALGO_MD5参数并且把加密串转2进制 pack(“H” .
strlen($sign), $sign)
相关文章
本站已关闭游客评论,请登录或者注册后再评论吧~