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 。

這是因為想要正確的使用密鑰,需要滿足以下三個條件。

  1. 公共密鑰的開頭需要加上"-----BEGIN RSA PUBLIC KEY-----\n",結尾需要加上"\n-----BEGIN RSA PUBLIC KEY-----\n"。不然會報 error:0906D06C:PEM routines:PEM_read_bio:no start line 。
  2. 公鑰字符串每隔64隔字符需要加一個換行,負責會報 error:0906D06C:PEM routines:PEM_read_bio:no start line 。
  3. 以上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-----

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM