zoukankan      html  css  js  c++  java
  • 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----- ",结尾需要加上" -----BEGIN RSA PUBLIC KEY----- "。不然会报 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, "
    ", 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-----
  • 相关阅读:
    hihocoder 1142 三分·三分求极值(三分)
    poj 3304 Segments(计算直线与线段之间的关系)
    poj 1269 Intersecting Lines(判断两直线关系,并求交点坐标)
    poj 2398 Toy Storage(计算几何 点线关系)
    poj 2318 TOYS(计算几何 点与线段的关系)
    计算几何基础(模板)
    Jmeter-基本组成
    java-面向对象
    性能测试基础
    java-多线程
  • 原文地址:https://www.cnblogs.com/johnson108178/p/9590956.html
Copyright © 2011-2022 走看看