上次在接入支付宝的时候就碰到了交易订单处理失败,请稍后再试(ALI64)这样的错误,后来经过排查和总结,一般来讲这种问题都是公钥和私钥没有正确配置造成的。支付宝这边为了保证数据在传输时不被篡改,使用了rsa这种非对称的加密方式。大概的流程如下:
理解这种流程后,因为支付宝的密钥我们是看不到,需要检测我们自己的公钥和密钥,还有支付宝的公钥。
公钥不是一行
实际中的话,我们下载支付宝的公钥,可以看到公钥是一行的。常见的格式都有带BEGIN PUBLIC KEY、END PUBLIC KEY这样的字眼:
-----BEGIN PUBLIC KEY——......-----END PUBLIC KEY——
这里需要把自己的公钥调整为一行,删除换行、头尾begin、end行。
公钥没有传到支付宝服务器
这个有时会忘记掉,因为支付宝要用我们的公钥解开我们传递到支付宝的数据,所以需要将我们自己的公钥上传到支付宝服务器,记的搞成一行。另外还有一个要注意的是,可以传公钥的地方都可以传一下。如下图合作伙伴密钥管理、开放平台密钥管理、无线产品密钥管理都需要传一下。我估计这三个是用在不同的业务上。
私钥格式不对
私钥的格式有多种,如:pem、pkcs、der等格式,不同的程序语言在处理上需要的格式不一样,php处理用openssl_get_privatekey需要pem格式,java可以处理pkcs格式。这方面稍微注意下。
上面说到公钥和和私钥的问题,支付宝有提供一个工具可以用来检测,上次我们也是通过这个工具才检测出是私钥格式不对造成的。
这里附上生成公钥,密钥的方式
用openssl工具生成:
生成私钥pem
$ openssl genrsa -out rsa_private_key.pem 1024
此时会在当前目录生成rsa_private_key.pem文件,php私钥就是用这个文件。
生成公钥
$ openssl rsa -in rsa_private_key.pem -pubout -out rsa_public_key.pem
此时会在当前目录生成rsa_public_key.pem文件,这个就是公钥文件,上传到淘宝的就是这个,注意去除掉换行、头和尾的begin和end。
如果你需要使用pkcs8格式,可以按照如下生成:
$ openssl pkcs8 -topk8 -inform PEM -in rsa_private_key.pem -outform PEM -nocrypt