error:0906D064:PEM routines:PEM_read_bio:bad base64 decode
今天在使用easywechat对接企业打款到银行卡时,遇到了两个错误
error:0906d064:pem routines:pem_read_bio:bad base64 decode 和 error:0906d06c:pem routines:pem_read_bio:no start line 。
这是因为想要正确的使用密钥,需要满足以下三个条件。
- 公共密钥的开头需要加上"-----begin rsa public key-----\n",结尾需要加上"\n-----begin rsa public key-----\n"。不然会报 error:0906d06c:pem routines:pem_read_bio:no start line 。
- 公钥字符串每隔64隔字符需要加一个换行,负责会报 error:0906d06c:pem routines:pem_read_bio:no start line 。
- 以上2步应该可以满足有些语言的需求,但php不行,还需要讲以上pkcs#1 格式密钥转换成pkcs#8 格式密钥。
下面看下具体操作。按照文档使用如下命令:
./vendor/bin/easywechat payment:rsa_public_key \ --mch_id=14339221228 \ --api_key=36ytbdmlgyq52noqdxgwgiyy \ --cert_path=/users/overtrue/www/demo/apiclient_cert.pem \ --key_path=/users/overtrue/www/demo/apiclient_key.pem
将会在当前目录生成一个 ./public-14339221228.pem
文件。
如果直接使用这个public key文件,会报一个非法的key错误,然后可以发现easywechat有这样一段源码。
function rsa_public_encrypt($content, $publickey) { $encrypted = ''; openssl_public_encrypt($content, $encrypted, openssl_pkey_get_public($publickey), openssl_pkcs1_oaep_padding); return base64_encode($encrypted); }
报非法key是因为 openssl_pkey_get_public($publickey) 返回的是false,这时,你可以加一行代码。
function rsa_public_encrypt($content, $publickey) { $encrypted = ''; openssl_public_encrypt($content, $encrypted, openssl_pkey_get_public($publickey), openssl_pkcs1_oaep_padding); var_dump(openssl_error_string()); return base64_encode($encrypted); }
这是会看到以下错误。
error:0906d06c:pem routines:pem_read_bio:no start line
这是因为easywechat直接生成的 public-14339221228.pem 文件中,key的格式是这样的。
-----begin rsa public key-----miibcgkcaqeauvvw3dewx4wddl2/i0aamma2bh3hhu89rqmhjwvq41urbatxzxmz13iemxg8uftbr+ugl+nczpkktjjcvm/2tcidwgzclr3rzo4xd5hrls8exi+uzknmar......cmtgtkwkqkhcnlwr7brrzbui3po7udlwpeprh1icd83/widaqab-----end rsa public key-----
这种格式是错误的,无法直接放到函数 openssl_pkey_get_public 中使用。需要对他进行格式化成如下形式。
-----begin rsa public key----- miibijanbgkqhkig9w0baqefaaocaq8amiibcgkcaqeauvvw3dewx4wddl2/i0aa mma2bh3hhu89rqmhjwvq41urbatxzxmz13iemxg8uftbr+ugl+nczpkktjjcvm/2 ...... ...... exfydteykuimuhn3a7wwnkc3vohml9c4kdwdjrx3wjqrwzbw3p3f1o/9pghlnzn9 p3la2c9/ve3jldg8lezvkcmtgtkwkqkhcnlwr7brrzbui3po7udlwpeprh1icd83 /widaqab -----end rsa public key-----
第一行是 -----begin rsa public key----- ,最后一行是 -----end rsa public key----- ,然后中间的key每64个字符一行,可以用php的
wordwrap($key, 64, "\n", true)
函数处理。但这种是pkcs#1 格式密钥。php是函数 openssl_pkey_get_public 也无法使用。需要将其转换成pkcs#8 格式密钥。可以用如下命令
openssl rsa -rsapublickey_in -in public-14339221228.pem -out public.pem
这种就是在当前目录得到一个 public.pem 文件。里面存放的是pkcs#8 格式密钥。这种密钥格式是php可以使用的。密钥如下:
-----begin public key----- miibijanbgkqhkig9w0baqefaaocaq8amiibcgkcaqeauvvw3dewx4wddl2/i0aa mma2bh3hhu89rqmhjwvq41urbatxzxmz13iemxg8uftbr+ugl+nczpkktjjcvm/2 ...... ...... exfydteykuimuhn3a7wwnkc3vohml9c4kdwdjrx3wjqrwzbw3p3f1o/9pghlnzn9 p3la2c9/ve3jldg8lezvkcmtgtkwkqkhcnlwr7brrzbui3po7udlwpeprh1icd83 /widaqab -----end public key-----
下一篇: 24种设计模式及七大设计原则