1.1 认证流程
安全API接口认证方案 流程图模板_ProcessOn思维导图、流程图www.processon.com/view/link/636e05a21e085317c6a688d2
1)官方配置Token验证
Token不在网络中传递
2)开发一个Token验证接口
Token及其它参数拼接并字典排序再做sha摘要计算
微信定期调用此接口来验证身份正确性
通过摘要验证判断请求来源微信(Token配置在微信平台,固而判断来源)
3)通过appid secret获取access_token
4)所有业务URL直接拼接access_token
5)针对报文安全可以设置加密模式,使用在平台配置的AESkey进行加密
1.2 参考代码
- 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;
- }
- }
1.3 小结
安全核心在于:
1、定时的Token验证
2、全部接口在https基础下请求
3、access_token具有时效性
4、AES增加安全系数
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
请求随机串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";
- }
p.s.你会发现好像都有oauth2的影子,如果你的系统没有上oauth2框架可以考虑结合微信支付或者微信公众号的方式做一个接口认证。其中核心就是摘要算法、非对称签名算法、对称加密算法。