天天看點

微信公衆号、支付接口認證:一步步教您如何實作

作者:玄明Hanko

#挑戰30天在頭條寫日記#

1、微信公衆号接口認證方案

1.1 認證流程

微信公衆号、支付接口認證:一步步教您如何實作

1)官方配置Token驗證

  • Token不在網絡中傳遞

2)開發一個Token驗證接口

  • Token及其它參數拼接并字典排序再做sha摘要計算
  • 微信定期調用此接口來驗證身份正确性
  • 通過摘要驗證判斷請求來源微信(Token配置在微信平台,固而判斷來源)

3)通過appid secret擷取access_token

4)所有業務URL直接拼接access_token

5)針對封包安全可以設定加密模式,使用在平台配置的AESkey進行加密

1.2 參考代碼

以下是官方提供的php demo

private function checkSignature()
{
  $signature = $_GET["signature"];
  $timestamp = $_GET["timestamp"];
  $nonce = $_GET["nonce"];

  $token = TOKEN;
  $tmpArr = array($token, $timestamp, $nonce);
  sort($tmpArr, SORT_STRING);
  $tmpStr = implode( $tmpArr );
  $tmpStr = sha1( $tmpStr );

  if( $tmpStr == $signature ){
    return true;
  }else{
    return false;
  }
}           

以下是chatgpt直接把php轉成java的代碼:

private boolean checkSignature() {
    String signature = request.getParameter("signature");
    String timestamp = request.getParameter("timestamp");
    String nonce = request.getParameter("nonce");

    String token = TOKEN;
    String[] tmpArr = {token, timestamp, nonce};
    Arrays.sort(tmpArr);
    String tmpStr = String.join("", tmpArr);
    tmpStr = sha1(tmpStr);

    if (tmpStr.equals(signature)) {
        return true;
    } else {
        return false;
    }
}
           

https://developers.weixin.qq.com/doc/offiaccount/Getting_Started/Overview.html

1.3 小結

微信公衆号接口認證方案即是基于oauth2的token認證機制

微信公衆号、支付接口認證:一步步教您如何實作

接口安全認證的核心在于:

1、定期的Token驗證

2、接口全部在https基礎下請求

3、access_token具有時效性

4、AES增加安全系數

其實不難看出微信公衆号的核心思想就是Oauth2認證協定。不過在基礎上增加了定期Token驗證的機制來保證請求的來源是微信。

2、微信支付接口認證方案

2.1 認證流程

微信公衆号、支付接口認證:一步步教您如何實作

微信公衆平台開發概述 | 微信開放文檔

1)在微信官方配置并擷取

a、appid mchid(商戶id)

b、api key(API v3密鑰)即AES-256-GCM 對稱加密密鑰。

c、商戶API證書(商戶的證書是通過下載下傳微信證書申請工具進行申請的)

d、微信支付平台證書即平台的公鑰證書用于加密業務接口的敏感封包。

2)生成簽名值(發送請求時:用戶端使用自己的私鑰簽名資料,讓伺服器驗簽。伺服器響應的封包與會簽名,并建議用戶端回收封包後也進行驗簽。)

a、簽名結構體

HTTP請求方法\n
URL\n
請求時間戳\n
請求随機串\n
請求封包主體\n           

b、使用商戶API私鑰(merchantPrivateKey)對以上資料進行SHA256 with RSA然後生成

Base64編碼字元串。

3)生成HTTP頭中的Authorization資料,Authorization由認證類型和簽名資訊兩個部分組成

a、認證類型,目前為WECHATPAY2-SHA256-RSA2048

b、簽名資訊

    • 發起請求的商戶(包括直連商戶、服務商或管道商)的商戶号mchid
    • 商戶API證書序列号serial_no,用于聲明所使用的證書
    • 請求随機串nonce_str
    • 時間戳timestamp
    • 簽名值signature

4)使用帶Authorization的HTTP請求,調用業務接口

2.2 參考代碼

import okhttp3.HttpUrl;
import java.security.Signature;
import java.util.Base64;
String schema = "WECHATPAY2-SHA256-RSA2048";
HttpUrl httpurl = HttpUrl.parse(url);

String getToken(String method, HttpUrl url, String body) {
    String nonceStr = "your nonce string";
    long timestamp = System.currentTimeMillis() / 1000;
    String message = buildMessage(method, url, timestamp, nonceStr, body);
    String signature = sign(message.getBytes("utf-8"));

    return "mchid=\"" + yourMerchantId + "\","
    + "nonce_str=\"" + nonceStr + "\","
    + "timestamp=\"" + timestamp + "\","
    + "serial_no=\"" + yourCertificateSerialNo + "\","
    + "signature=\"" + signature + "\"";
}

String sign(byte[] message) {
    Signature sign = Signature.getInstance("SHA256withRSA");
    sign.initSign(yourPrivateKey);
    sign.update(message);

    return Base64.getEncoder().encodeToString(sign.sign());
}

String buildMessage(String method, HttpUrl url, long timestamp, String nonceStr, String body) {
    String canonicalUrl = url.encodedPath();
    if (url.encodedQuery() != null) {
      canonicalUrl += "?" + url.encodedQuery();
    }

    return method + "\n"
        + canonicalUrl + "\n"
        + timestamp + "\n"
        + nonceStr + "\n"
        + body + "\n";
}           

https://wechatpay-api.gitbook.io/wechatpay-api-v3/

2.3 小結

微信支付接口認證方案即是基于數字簽名的技術方案。數字簽名借助于數字證書可保證通信的身份與資料不被篡改。

微信公衆号、支付接口認證:一步步教您如何實作

p.s.如果考慮資料的安全微信支付也支援對封包進行AES-256-GCM對稱加密。

3、總結

  • 微信公衆号接口認證方案即是基于oauth2的token認證機制
  • 微信支付接口認證方案即是基于數字簽名的技術方案
微信公衆号、支付接口認證:一步步教您如何實作

======================================

如果文章對你有幫助,請不要忘記加個關注、點個贊!

繼續閱讀