證書和回調(diào)報(bào)文解密
為了保證安全性,微信支付在回調(diào)通知和平臺證書下載接口中,對關(guān)鍵信息進(jìn)行了AES-256-GCM加密。本章節(jié)詳細(xì)介紹了加密報(bào)文的格式,以及如何進(jìn)行解密。
為了保證安全性,微信支付在回調(diào)通知和平臺證書下載接口中,對關(guān)鍵信息進(jìn)行了AES-256-GCM加密。本章節(jié)詳細(xì)介紹了加密報(bào)文的格式,以及如何進(jìn)行解密。
AES-GCM是一種NIST標(biāo)準(zhǔn)的認(rèn)證加密算法, 是一種能夠同時(shí)保證數(shù)據(jù)的保密性、 完整性和真實(shí)性的一種加密模式。它最廣泛的應(yīng)用是在TLS中。
證書和回調(diào)報(bào)文使用的加密密鑰為APIv3密鑰。
對于加密的數(shù)據(jù),我們使用了一個(gè)獨(dú)立的JSON對象來表示。為了方便閱讀,示例做了Pretty格式化,并加入了注釋。
{
"original_type": "transaction", // 加密前的對象類型
"algorithm": "AEAD_AES_256_GCM", // 加密算法
// Base64編碼后的密文
"ciphertext": "...",
// 加密使用的隨機(jī)串初始化向量)
"nonce": "...",
// 附加數(shù)據(jù)包(可能為空)
"associated_data": ""
}
算法接口的細(xì)節(jié),可以參考RFC 5116。
大部分編程語言(較新版本)都支持了AEAD_AES_256_GCM 。開發(fā)者可以參考下列的示例,了解如何使用您的編程語言實(shí)現(xiàn)解密。
package com.wechat.v3;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.wechat.pay.contrib.apache.httpclient.exception.ParseException;
import com.wechat.pay.contrib.apache.httpclient.util.AesUtil;
import java.nio.charset.StandardCharsets;
import java.security.GeneralSecurityException;
class DecodeCipher {
private static final String apiV3Key = "";
private void setDecryptData(Notification notification) throws ParseException {
Notification.Resource resource = notification.getResource();
String getAssociateddData = "";
if (resource.getAssociatedData() != null) {
getAssociateddData = resource.getAssociatedData();
}
byte[] associatedData = getAssociateddData.getBytes(StandardCharsets.UTF_8);
byte[] nonce = resource.getNonce().getBytes(StandardCharsets.UTF_8);
String ciphertext = resource.getCiphertext();
AesUtil aesUtil = new AesUtil(apiV3Key.getBytes(StandardCharsets.UTF_8));
String decryptData;
try {
decryptData = aesUtil.decryptToString(associatedData, nonce, ciphertext);
} catch (GeneralSecurityException e) {
throw new ParseException("AES解密失敗,resource:" + resource.toString(), e);
}
notification.setDecryptData(decryptData);
}
@JsonIgnoreProperties(ignoreUnknown = true)
public class Notification {
@JsonProperty("id")
private String id;
@JsonProperty("create_time")
private String createTime;
@JsonProperty("event_type")
private String eventType;
@JsonProperty("resource_type")
private String resourceType;
@JsonProperty("summary")
private String summary;
@JsonProperty("resource")
private Resource resource;
private String decryptData;
@Override
public String toString() {
return "Notification{" +
"id='" + id + '\'' +
", createTime='" + createTime + '\'' +
", eventType='" + eventType + '\'' +
", resourceType='" + resourceType + '\'' +
", decryptData='" + decryptData + '\'' +
", summary='" + summary + '\'' +
", resource=" + resource +
'}';
}
public String getId() {
return id;
}
public String getCreateTime() {
return createTime;
}
public String getEventType() {
return eventType;
}
public String getDecryptData() {
return decryptData;
}
public String getSummary() {
return summary;
}
public String getResourceType() {
return resourceType;
}
public Resource getResource() {
return resource;
}
public void setDecryptData(String decryptData) {
this.decryptData = decryptData;
}
@JsonIgnoreProperties(ignoreUnknown = true)
public class Resource {
@JsonProperty("algorithm")
private String algorithm;
@JsonProperty("ciphertext")
private String ciphertext;
@JsonProperty("associated_data")
private String associatedData;
@JsonProperty("nonce")
private String nonce;
@JsonProperty("original_type")
private String originalType;
public String getAlgorithm() {
return algorithm;
}
public String getCiphertext() {
return ciphertext;
}
public String getAssociatedData() {
return associatedData;
}
public String getNonce() {
return nonce;
}
public String getOriginalType() {
return originalType;
}
@Override
public String toString() {
return "Resource{" +
"algorithm='" + algorithm + '\'' +
", ciphertext='" + ciphertext + '\'' +
", associatedData='" + associatedData + '\'' +
", nonce='" + nonce + '\'' +
", originalType='" + originalType + '\'' +
'}';
}
}
}
}
Customer Service Tel
Business Development
9:00-18:00
Monday-Friday GMT+8
Technical Support
WeChat Pay Global
ICP證