Skip to content

Commit

Permalink
Merge pull request #12 from wechatpay-apiv3/v0.1.6
Browse files Browse the repository at this point in the history
V0.1.6
  • Loading branch information
xy-peng authored May 14, 2020
2 parents 3620c95 + 75beb32 commit 8fe8e1b
Show file tree
Hide file tree
Showing 4 changed files with 73 additions and 19 deletions.
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

## 项目状态

当前版本`0.1.5`为测试版本。请商户的专业技术人员在使用时注意系统和软件的正确性和兼容性,以及带来的风险。
当前版本`0.1.6`为测试版本。请商户的专业技术人员在使用时注意系统和软件的正确性和兼容性,以及带来的风险。

## 环境要求

Expand All @@ -27,7 +27,7 @@ repositories {
}
...
dependencies {
implementation 'com.github.wechatpay-apiv3:wechatpay-apache-httpclient:0.1.5'
implementation 'com.github.wechatpay-apiv3:wechatpay-apache-httpclient:0.1.6'
...
}
```
Expand All @@ -51,7 +51,7 @@ dependencies {
<dependency>
<groupId>com.github.wechatpay-apiv3</groupId>
<artifactId>wechatpay-apache-httpclient</artifactId>
<version>0.1.5</version>
<version>0.1.6</version>
</dependency>
```

Expand Down
10 changes: 5 additions & 5 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ plugins {
}

group 'com.github.wechatpay-apiv3'
version '0.1.4'
version '0.1.6'

sourceCompatibility = 1.8
targetCompatibility = 1.8
Expand All @@ -14,15 +14,15 @@ repositories {
}

ext {
httpclient_version = "4.5.8"
slf4j_version = "1.7.26"
httpclient_version = "4.5.12"
slf4j_version = "1.7.30"
junit_version = "4.12"
jackson_version = "2.9.7"
jackson_version = "2.9.10"
}

dependencies {
api "org.apache.httpcomponents:httpclient:$httpclient_version"
api "com.fasterxml.jackson.core:jackson-databind:$jackson_version"
implementation "com.fasterxml.jackson.core:jackson-databind:$jackson_version"
implementation "org.slf4j:slf4j-api:$slf4j_version"
testImplementation "org.slf4j:slf4j-simple:$slf4j_version"
testImplementation "junit:junit:$junit_version"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import java.io.IOException;
import java.security.GeneralSecurityException;
import java.security.cert.CertificateExpiredException;
import java.security.cert.CertificateFactory;
import java.security.cert.CertificateNotYetValidException;
import java.security.cert.X509Certificate;
import java.time.Duration;
Expand Down Expand Up @@ -143,8 +144,10 @@ private List<X509Certificate> deserializeToCerts(byte[] apiV3Key, String body)
.getBytes("utf-8"),
encryptCertificateNode.get("ciphertext").toString().replaceAll("\"", ""));

X509Certificate x509Cert = PemUtil
.loadCertificate(new ByteArrayInputStream(cert.getBytes("utf-8")));
CertificateFactory cf = CertificateFactory.getInstance("X509");
X509Certificate x509Cert = (X509Certificate) cf.generateCertificate(
new ByteArrayInputStream(cert.getBytes("utf-8"))
);
try {
x509Cert.checkValidity();
} catch (CertificateExpiredException | CertificateNotYetValidException e) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@

import com.wechat.pay.contrib.apache.httpclient.Validator;
import java.io.IOException;
import java.time.DateTimeException;
import java.time.Duration;
import java.time.Instant;
import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
Expand All @@ -19,24 +22,72 @@ public WechatPay2Validator(Verifier verifier) {
this.verifier = verifier;
}

static RuntimeException parameterError(String message, Object... args) {
message = String.format(message, args);
return new IllegalArgumentException("parameter error: " + message);
}

static RuntimeException verifyFail(String message, Object... args) {
message = String.format(message, args);
return new IllegalArgumentException("signature verify fail: " + message);
}

@Override
public final boolean validate(CloseableHttpResponse response) throws IOException {
Header serialNo = response.getFirstHeader("Wechatpay-Serial");
Header sign = response.getFirstHeader("Wechatpay-Signature");
Header timestamp = response.getFirstHeader("Wechatpay-TimeStamp");
Header nonce = response.getFirstHeader("Wechatpay-Nonce");
try {
validateParameters(response);

String message = buildMessage(response);
String serial = response.getFirstHeader("Wechatpay-Serial").getValue();
String signature = response.getFirstHeader("Wechatpay-Signature").getValue();

// todo: check timestamp
if (timestamp == null || nonce == null || serialNo == null || sign == null) {
if (!verifier.verify(serial, message.getBytes("utf-8"), signature)) {
throw verifyFail("serial=[%s] message=[%s] sign=[%s], request-id=[%s]",
serial, message, signature,
response.getFirstHeader("Request-ID").getValue());
}
} catch (IllegalArgumentException e) {
log.warn(e.getMessage());
return false;
}

String message = buildMessage(response);
return verifier.verify(serialNo.getValue(), message.getBytes("utf-8"), sign.getValue());
return true;
}

protected final void validateParameters(CloseableHttpResponse response) {
String requestId;
if (!response.containsHeader("Request-ID")) {
throw parameterError("empty Request-ID");
} else {
requestId = response.getFirstHeader("Request-ID").getValue();
}

if (!response.containsHeader("Wechatpay-Serial")) {
throw parameterError("empty Wechatpay-Serial, request-id=[%s]", requestId);
} else if (!response.containsHeader("Wechatpay-Signature")){
throw parameterError("empty Wechatpay-Signature, request-id=[%s]", requestId);
} else if (!response.containsHeader("Wechatpay-Timestamp")) {
throw parameterError("empty Wechatpay-Timestamp, request-id=[%s]", requestId);
} else if (!response.containsHeader("Wechatpay-Nonce")) {
throw parameterError("empty Wechatpay-Nonce, request-id=[%s]", requestId);
} else {
Header timestamp = response.getFirstHeader("Wechatpay-Timestamp");
try {
Instant instant = Instant.ofEpochSecond(Long.parseLong(timestamp.getValue()));
// 拒绝5分钟之外的应答
if (Duration.between(instant, Instant.now()).abs().toMinutes() >= 5) {
throw parameterError("timestamp=[%s] expires, request-id=[%s]",
timestamp.getValue(), requestId);
}
} catch (DateTimeException | NumberFormatException e) {
throw parameterError("invalid timestamp=[%s], request-id=[%s]",
timestamp.getValue(), requestId);
}
}
}

protected final String buildMessage(CloseableHttpResponse response) throws IOException {
String timestamp = response.getFirstHeader("Wechatpay-TimeStamp").getValue();
String timestamp = response.getFirstHeader("Wechatpay-Timestamp").getValue();
String nonce = response.getFirstHeader("Wechatpay-Nonce").getValue();

String body = getResponseBody(response);
Expand Down

0 comments on commit 8fe8e1b

Please sign in to comment.