微信支付企業付款到銀行卡——一鍵生成公鑰RSA加密,以及測試

wavebossy6666發表於2021-08-28

程式碼備份錄——一鍵生成公鑰(很討厭某些人,寫個demo介面還要收費?)

程式碼

<?php

namespace App\Console\Commands;

use App\Traits\bladeTrait;
use Illuminate\Console\Command;
use Illuminate\Support\Str;

class PublicEm extends Command{
    use bladeTrait;
    protected $signature = 'command:pub-key';
    protected $description = '用於生成生成微信商戶號付款至銀行卡的公鑰,需要在伺服器使用';

    /**
     * 1、env檔案配置商戶號和key
     * 2、生成public.pem檔案
     * 3、轉換publicpkcs8.pem檔案
     * 4、測試加密內容
     * apiclient_cert.p12
     * @return mixed
     */
    public function handle(){

        $mch_id = env("PROJECT_MCH_ID");
        $key = env("PROJECT_MCH_KEY");

        echo "讀取配置" . PHP_EOL;
        echo "商戶號" .$mch_id. PHP_EOL;
        echo "祕鑰" .$key. PHP_EOL;
        echo "開始生成public.pem" . PHP_EOL;

        $data = [
            "mch_id"=>$mch_id,
            "nonce_str"=>Str::random(32),
            "sign_type"=>"MD5",
        ];

        ksort($data);
        $headData = $this->newToUrlParams($data);
        $sign = strtoupper(md5($headData."&key=".$key));
        $data = array_merge($data,[
            "sign"=>$sign
        ]);

        $xmlData = $this->newToXml($data);
        $curl = curl_init(); curl_setopt($curl,CURLOPT_URL,"https://fraud.mch.weixin.qq.com/risk/getpublickey");
        curl_setopt($curl,CURLOPT_RETURNTRANSFER,true);
        curl_setopt($curl,CURLOPT_POST,true);
        curl_setopt($curl,CURLOPT_POSTFIELDS,$xmlData);
        curl_setopt($curl,CURLOPT_SSL_VERIFYPEER, true);
        curl_setopt($curl,CURLOPT_SSL_VERIFYHOST, 2);
        curl_setopt($curl,CURLOPT_SSLCERTTYPE,'PEM');
        curl_setopt($curl,CURLOPT_SSLCERT,app_path('Cert/'.$mch_id.'apiclient_cert.pem'));
        curl_setopt($curl,CURLOPT_SSLKEYTYPE,'PEM');
        curl_setopt($curl,CURLOPT_SSLKEY,app_path('Cert/'.$mch_id.'apiclient_key.pem'));
        $string = curl_exec($curl);
        $error = curl_error($curl);
        curl_close($curl);
        if($error){
            echo "curl失敗" . PHP_EOL;
            echo $error . PHP_EOL;
            return;
        }else{
            echo "curl成功" . PHP_EOL;
            $strpostData = simplexml_load_string($string);
            $stringData = [];
            foreach ($strpostData->children() as $child){
                $stringData = array_merge($stringData,array($child->getName()=>(string)$child));
            } file_put_contents(app_path("Cert")."/".$stringData["mch_id"]."public.pem",$stringData["pub_key"]);

            echo "生成檔案成功" . PHP_EOL;

            // linux命令轉換證照格式
            // openssl rsa -RSAPublicKey_in -in 1456790502public.pem -pubout

            exec("
            cd ".app_path("Cert")." \n
            openssl rsa -RSAPublicKey_in -in ".$stringData["mch_id"]."public.pem -pubout", $result, $var);

            echo "pem轉pkcs8成功" . PHP_EOL;
            foreach ($result as $item){ file_put_contents(app_path("Cert")."/".$stringData["mch_id"]."public_pkcs8.pem",$item.PHP_EOL,FILE_APPEND);
            }

            echo "測試加密欄位..." . PHP_EOL;

            $data = "張三";
            $pub_key = file_get_contents(app_path("Cert")."/".$mch_id."publicpkcs8.pem");
            $r = openssl_public_encrypt($data,$encrypt_data,$pub_key,OPENSSL_PKCS1_PADDING);

            if($r){
                echo "測試正常..." . PHP_EOL;
                echo base64_encode($encrypt_data). PHP_EOL;
            }else{
                echo "測試異常..." . PHP_EOL;
            }
        }
    }
}

Trait

<?php
namespace App\Traits;
trait bladeTrait{
    public function newToXml($data){
        if(is_array($data) && count($data) > 0) {
            $xml = "<xml>";
            foreach ($data as $key=>$val) {
                $xml.="<".$key.">".$val."</".$key.">";
            }
            $xml.="</xml>";
            return $xml;
        }
        return "";
    }

    public function newToUrlParams($data){
        $buff = "";
        foreach ($data as $k => $v)
        {
            if($k != "sign" && $v != "" && !is_array($v)){
                $buff .= $k . "=" . $v . "&";
            }
        }
        $buff = trim($buff, "&");
        return $buff;
    }
}
本作品採用《CC 協議》,轉載必須註明作者和本文連結
朝著夢,踏平坎坷

相關文章