关于微信支付的平台证书以及证书序列号

在微信支付平台中申请的证书没有wechatpay_cert.pem

接下来就生成这个证书和 证书序列号

                
             $certificates = $this->getWechatpayCertificates(); //拿到数据
            if (!empty($certificates['data'])) {   //解密失败
                foreach ($certificates['data'] as $cert) {
                    $associated_data = $cert['encrypt_certificate']['associated_data'];
                    $nonce = $cert['encrypt_certificate']['nonce'];
                    $ciphertext = $cert['encrypt_certificate']['ciphertext'];
                    $serial_no = $cert['serial_no'];
                    $api_v3_key = 'qwertyuiopasdfghjklzxcvbnm123456'; // 替换为你的APIv3密钥
                    
                    $decrypted_certificate = $this->decryptWechatpayCertificate($associated_data, $nonce, $ciphertext, $api_v3_key);
                    
                    // 保存证书内容到文件
                    $cert_file_path = "/www/wwwroot/jyxcx.79524795.vip/extend/wechat/cert//wechatpay_cert_{$serial_no}.pem";
                    file_put_contents($cert_file_path, $decrypted_certificate);
                    echo "微信支付平台证书已保存到: $cert_file_path\n";
                }
            } else {
                echo "未能获取到微信支付平台证书。\n";
            }
             die;

逻辑层

public function getWechatpayCertificates()
{
    $url = "https://api.mch.weixin.qq.com/v3/certificates";
    $http_method = 'GET';
    $timestamp = time();
    $nonce_str = bin2hex(random_bytes(16));
    
    // 商户证书文件路径
    $cert_path = '你的证书地址/apiclient_cert.pem';
    $key_path = '你的证书地址/apiclient_key.pem';
    $merchant_id = '***********';  // 替换为你的商户号
    $merchant_serial_number = '**************';  // 替换为你的商户证书序列号

    // 检查文件是否存在
    if (!file_exists($cert_path)) {
        throw new Exception("证书文件不存在: $cert_path");
    }
    if (!file_exists($key_path)) {
        throw new Exception("密钥文件不存在: $key_path");
    }

    // 构造签名串
    $message = "$http_method\n/v3/certificates\n$timestamp\n$nonce_str\n\n";
    
    // 使用商户私钥进行签名
    $private_key = openssl_pkey_get_private(file_get_contents($key_path));
    openssl_sign($message, $raw_sign, $private_key, 'sha256WithRSAEncryption');
    $sign = base64_encode($raw_sign);
    openssl_free_key($private_key);

    // 构造Authorization头
    $authorization = sprintf(
        'WECHATPAY2-SHA256-RSA2048 mchid="%s",nonce_str="%s",signature="%s",timestamp="%d",serial_no="%s"',
        $merchant_id,
        $nonce_str,
        $sign,
        $timestamp,
        $merchant_serial_number
    );
    
    // 使用cURL发送请求
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($ch, CURLOPT_SSLCERT, $cert_path);
    curl_setopt($ch, CURLOPT_SSLKEY, $key_path);
    curl_setopt($ch, CURLOPT_HTTPHEADER, array(
        'Content-Type: application/json',
        'Accept: application/json',
        'User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3',
        'Authorization: ' . $authorization
    ));
    
    $response = curl_exec($ch);
    
    // 检查cURL错误
    if ($response === false) {
        $error = curl_error($ch);
        curl_close($ch);
        throw new Exception("cURL 请求错误: $error");
    }
    
    curl_close($ch);
    
    $result = json_decode($response, true);
    if (json_last_error() !== JSON_ERROR_NONE) {
        throw new Exception("JSON 解析错误: " . json_last_error_msg());
    }

    // var_dump($result); // 打印结果用于调试
    return $result;
}



 public function decryptWechatpayCertificate($associated_data, $nonce, $ciphertext, $api_v3_key)
{
    // Base64 decode the ciphertext
    $ciphertext = base64_decode($ciphertext);

    // Extract the authentication tag (last 16 bytes of the ciphertext)
    $tag = substr($ciphertext, -16);
    $ciphertext = substr($ciphertext, 0, -16);

    // OpenSSL decrypt
    $decrypted_data = openssl_decrypt(
        $ciphertext, 
        'aes-256-gcm', 
        $api_v3_key, 
        OPENSSL_RAW_DATA, 
        $nonce, 
        $tag, 
        $associated_data
    );

    if ($decrypted_data === false) {
        throw new Exception('解密失败');
    }

    return $decrypted_data;
}
posted @ 2024-06-18 22:27  79524795  阅读(5)  评论(0编辑  收藏  举报