对以下一段代码进行测试发现,在不同的php环境下,出现不同的执行效果。
/*读取公钥文件*/
$pubKey = file_get_contents($publicKeyFilePath);
/*转换为openssl格式密钥*/
$resource = openssl_get_publickey($pubKey);
var_dump($resource)
openssl_public_encrypt($block, $chrText, $resource);
在apache2.4.19+php5.6.19或者php7.0.13环境中 运行都正常,但是在apache 2.4.17 + php5.6.15环境中运行出现了以下错误key parameter is not a valid public key,error:0906D06C:PEM routines:PEM_read_bio:no start line这样的错误。打印resource,发现返回的是false。
经过不断排查,将公钥的单行切换成多行模式,测试通过。结合网上的相关资料,总结如下:
公钥中必须有-----BEGIN PUBLIC KEY----- 和 -----END PUBLIC KEY----- 。公钥必须断行,否则有可能无法读取到正确的公钥。比如使用php的openssl_pkey_get_public无法读取到公钥资源。
密钥文件最终将数据通过Base64编码进行存储。可以看到上述密钥文件内容每一行的长度都很规律。 之所以要对经过base64的公钥进行断行,这是由于RFC2045中规定:The encoded output stream must be represented in lines of no more than 76 characters each。也就是说Base64编码的数据每行最多不超过76字符,对于超长数据需要按行分割。支付宝公钥是64位分割的。