PHP openssl_public_encrypt加密失败返回空值原因是公钥或私钥格式不对

测试环境:Mac + Nginx + php 7.1

用工具(比如支付宝开放平台开发助手)生成一对RSA公钥和私钥,尝试用PHP openssl_public_encrypt加密,结果返回空。

$data = '要加密的数据';
$public_key = 'MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAMTFlbLNQ6Q8aFmA9KNXi963zYIFOm9v';
$public_key = '-----BEGIN PUBLIC KEY-----' . $public_key . '-----END PUBLIC KEY-----';
$openssl_public_encrypt($data, $encrypted, $public_key);

if (empty($encrypted)) {
    echo 'failed to encrypt';
}
else {
    echo 'success';
}

查阅资料后,发现原来Linux系统中PHP加密用的公钥和私钥需要换行处理,所以手动换行即可,一行64位:

$public_key = "-----BEGIN PUBLIC KEY-----\n" .
            wordwrap($public_key, 64, "\n", true) .
            "\n-----END PUBLIC KEY-----";

私钥同理:

$private_key = "-----BEGIN PRIVATE KEY-----\n" .
            wordwrap($private_key, 64, "\n", true) .
            "\n-----END PRIVATE KEY-----";

用PHP语法openssl_pkey_new生成公钥和私钥,原样打印保存至文件中,看得出,确实是自带换行了。

很多地方涉及钥匙的内容是一大行,必须要注意系统环境。

如果公钥能加密,但私钥不能解密,那就需要看下首尾抬头了,可能要额外添加RSA标识:

$private_key = "-----BEGIN RSA PRIVATE KEY-----\n" .
            wordwrap($private_key, 64, "\n", true) .
            "\n-----END RSA PRIVATE KEY-----";

具体BEGIN PRIVATE KEYBEGIN RSA PRIVATE KEY有什么区别,请看参考资料吧,笔者没怎么看明白,反正大概就是原理不同,有时间再研究。

参考资料

https://www.jianshu.com/p/f416d16fc935

https://www.lmlphp.com/user/16536/article/item/511970/

(版权归cpury.com所有,转载请注明出处。)