建设银行支付接口开发中的接收通知和审核签字问题
最近在做建行的B2B支付接口(B2C和B2B类似)。
付款成功后,我们会收到银行的通知,并检查问题和解决方案,现在逐一记下:
建行提供的DEMO php版本用的是COM组件,但是我的服务器是LINUX,不支持COM组件(听说网上有支持的方法,太累了,放弃不了)。
用PHP调用JAVA类还有另外一种方法(PHP-Java-Bridge方法,这里不谈百度)。
这里,我们来谈谈使用PHP的openssl_verify进行检查和签名。请慢慢跟我来。
以下是步骤:
1.openssl_verify需要一个PEM格式的公钥才能从CCB下载一个公钥(CCB提供的一个公钥是字符串和十六进制的字符串,你下载的公钥不一样,每次都会改变。这张纸条)
2.尝试将这串十六进制公钥转换成PEM格式,百度发现没有具体方案。现在给出的php代码可以通过下面的代码转换成PEM格式。
函数der2pem($der_data)
{
$ PEM=chunk _ split(base64 _ encode(hex 2 bin($ der _ data)),64,' n ');
$pem=' - BEGIN公钥- n '。$pem。-结束公钥- n ';
返回$ pem
}
方法调用:der2pem('公钥字符串');
3.检查并签名(php代码如下)
/**
*验证签名
* @param数组$val原始字符串
* @param type $sign加密字符串
*/
公共函数verifySign($val,$sign)
{
$ data=
foreach ($val为$k=$v)
{
如果( org util String:3360是UTF8($ v))//判断编码UTF8需要转换。
{
$数据。=iconv('utf-8 ',' gbk ',$ v);
}
其他
{
$数据。=$ v;
}
}
$ public _ key=self : PubKey;
$ public _ key=FIle _ get _ contents(dir name(_ _ FILE _ _)。'/' .$ public _ key);
$ pkeyid=OpenSSL _ get _ public key($ public _ key);
$ verifyResult=open SSL _ verify($ data,pack('H ')。strlen($sign)、$sign)、$pkeyid、OPENSSL _ ALGO _ MD5);
OpenSSL _ free _ key($ pkeyid);
返回$verifyResult==1?真:假;
}
4.特殊说明:
A.建行的加密参数是GBK的,所以校验签字时UTF8的编码要转移到GBK的。
B.CCB页面通知get参数没有中文URL编码,在ie下可能全部乱码(使用THINKPHP框架的I方法无法获取包含中文的参数,应该使用原生的$_GET方法)
c.openssl_verify($data,pack('H ')。strlen($sign)、$sign)、$pkeyid、OPENSSL _ ALGO _ MD5);
//建行采用rsawithmd5的加密方式。检查所有签名时,应使用OPENSSL_ALGO_MD5参数,并将加密字符串传输到二进制包(' H ')。strlen($sign),$sign)。