Skip to content

Commit

Permalink
回调和回包验签支持平台公钥
Browse files Browse the repository at this point in the history
  • Loading branch information
wujunjiesd committed Aug 20, 2024
1 parent 167e9c4 commit 1259626
Show file tree
Hide file tree
Showing 509 changed files with 2,654 additions and 34 deletions.
10 changes: 5 additions & 5 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,18 @@ jobs:
build:
strategy:
matrix:
java-version: [ 8, 11, 17 ]
java-version: [ 11, 17, 21 ]
os: [ubuntu-latest, macos-latest, windows-latest]
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- name: Set up JDK
uses: actions/setup-java@v3
uses: actions/setup-java@v4
with:
java-version: ${{ matrix.java-version }}
distribution: 'temurin'
cache: 'gradle'
- name: Validate Gradle wrapper
uses: gradle/wrapper-validation-action@v1
uses: gradle/actions/wrapper-validation@v3
- name: Build with Gradle
run: ./gradlew build
run: ./gradlew build
12 changes: 6 additions & 6 deletions .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ jobs:
check-tag:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- name: Regex Match
id: regex-match
run: |
Expand All @@ -26,19 +26,19 @@ jobs:
needs: [check-tag]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- name: Set up Java
uses: actions/setup-java@v3
uses: actions/setup-java@v4
with:
java-version: '8'
java-version: '17'
distribution: 'temurin'
- name: Validate Gradle wrapper
uses: gradle/wrapper-validation[email protected]
uses: gradle/actions/wrapper-validation@v3
# 发布项目
- name: Publish
run: ./gradlew publish
env:
SONATYPE_NEXUS_USERNAME: ${{secrets.SONATYPE_NEXUS_USERNAME}}
SONATYPE_NEXUS_PASSWORD: ${{secrets.SONATYPE_NEXUS_PASSWORD}}
SIGNING_KEY: ${{secrets.SIGNING_KEY}}
SIGNING_PASSWORD: ${{secrets.SIGNING_PASSWORD}}
SIGNING_PASSWORD: ${{secrets.SIGNING_PASSWORD}}
11 changes: 6 additions & 5 deletions .github/workflows/sonarcloud-scan.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,27 +9,28 @@ on:
- 'feat_*'
- 'fix_*'
- 'refactor_*'

jobs:
build:
name: Build
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v4
with:
fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis
- name: Set up JDK 17
uses: actions/setup-java@v1
uses: actions/setup-java@v4
with:
java-version: 17
distribution: 'temurin'
- name: Cache SonarCloud packages
uses: actions/cache@v1
uses: actions/cache@v4
with:
path: ~/.sonar/cache
key: ${{ runner.os }}-sonar
restore-keys: ${{ runner.os }}-sonar
- name: Cache Gradle packages
uses: actions/cache@v1
uses: actions/cache@v4
with:
path: ~/.gradle/caches
key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle') }}
Expand Down
5 changes: 4 additions & 1 deletion buildSrc/src/main/groovy/common.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ plugins {
id "jacoco"
}

sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8

version projectPropVersion
group projectPropGroup
compileJava.options.encoding = "UTF-8"
Expand All @@ -19,7 +22,7 @@ repositories {
spotless {
java {
removeUnusedImports()
googleJavaFormat('1.7')
googleJavaFormat('1.22.0')
}
}

Expand Down
2 changes: 1 addition & 1 deletion core/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ dependencies {
implementation "org.slf4j:slf4j-api:${slf4jVersion}"

testImplementation "junit:junit:${junitVersion}"
testImplementation "org.mockito:mockito-inline:${mockitoInlineVersion}"
testImplementation "org.mockito:mockito-core:${mockitoCoreVersion}"
testImplementation "com.squareup.okhttp3:mockwebserver:${okhttpVersion}"
testImplementation "org.awaitility:awaitility:${awaitilityVersion}"

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,14 +51,19 @@ protected AbstractRSAConfig(

/** 商户号 */
private final String merchantId;

/** 商户私钥 */
private final PrivateKey privateKey;

/** 商户证书序列号 */
private final String merchantSerialNumber;

/** 微信支付平台证书Provider */
private final CertificateProvider certificateProvider;

/** 微信支付平台公钥 */
private final PublicKey publicKey;

/** 微信支付平台公钥Id */
private final String publicKeyId;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,6 @@ public RSAPublicKeyConfig build() {
requireNonNull(publicKey);
requireNonNull(publicKeyId);
requireNonNull(privateKey);
requireNonNull(apiV3Key);
requireNonNull(merchantSerialNumber);

return new RSAPublicKeyConfig(this);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import com.wechat.pay.java.core.certificate.model.DownloadCertificateResponse;
import com.wechat.pay.java.core.certificate.model.EncryptCertificate;
import com.wechat.pay.java.core.cipher.AeadCipher;
import com.wechat.pay.java.core.exception.ServiceException;
import com.wechat.pay.java.core.http.Constant;
import com.wechat.pay.java.core.http.HttpClient;
import com.wechat.pay.java.core.http.HttpMethod;
Expand Down Expand Up @@ -76,10 +77,17 @@ public Map<String, X509Certificate> download() {
.addHeader(Constant.ACCEPT, " */*")
.addHeader(Constant.CONTENT_TYPE, MediaType.APPLICATION_JSON.getValue())
.build();
HttpResponse<DownloadCertificateResponse> httpResponse =
httpClient.execute(httpRequest, DownloadCertificateResponse.class);

return decryptCertificate(httpResponse);
try {
HttpResponse<DownloadCertificateResponse> httpResponse =
httpClient.execute(httpRequest, DownloadCertificateResponse.class);
return decryptCertificate(httpResponse);
} catch (ServiceException e) {
// 如果证书不存在,可能是切换为平台公钥,该处不报错
if (e.getErrorCode().equals("NOT_FOUND")) {
return new HashMap<>();
}
throw e;
}
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ protected AbstractVerifier(String algorithmName, CertificateProvider certificate
*
* @param algorithmName 获取Signature对象时指定的算法,例如SHA256withRSA
* @param publicKey 验签使用的微信支付平台公钥,非空
* @param publicKeyId 验签使用的微信支付平台公钥id
*/
protected AbstractVerifier(String algorithmName, PublicKey publicKey, String publicKeyId) {
this.publicKey = requireNonNull(publicKey);
Expand All @@ -48,6 +49,25 @@ protected AbstractVerifier(String algorithmName, PublicKey publicKey, String pub
this.certificateProvider = null;
}

/**
* AbstractVerifier 构造函数,仅在平台证书和平台公钥灰度切换阶段使用
*
* @param algorithmName 获取Signature对象时指定的算法,例如SHA256withRSA
* @param publicKey 验签使用的微信支付平台公钥,非空
* @param publicKeyId 验签使用的微信支付平台公钥id
* @param certificateProvider 验签使用的微信支付平台证书管理器,非空
*/
protected AbstractVerifier(
String algorithmName,
PublicKey publicKey,
String publicKeyId,
CertificateProvider certificateProvider) {
this.publicKey = requireNonNull(publicKey);
this.publicKeyId = publicKeyId;
this.algorithmName = requireNonNull(algorithmName);
this.certificateProvider = requireNonNull(certificateProvider);
}

protected boolean verify(X509Certificate certificate, String message, String signature) {
try {
Signature sign = Signature.getInstance(algorithmName);
Expand Down Expand Up @@ -87,15 +107,19 @@ public boolean verify(String serialNumber, String message, String signature) {
if (serialNumber.equals(publicKeyId)) {
return verify(message, signature);
}
logger.error("publicKeyId[{}] and serialNumber[{}] are not equal", publicKeyId, serialNumber);
return false;
// 如果证书为空,则说明是传入的publicKeyId错误,如果不为空,则继续使用证书验签
if (certificateProvider == null) {
logger.error(
"publicKeyId[{}] and serialNumber[{}] are not equal", publicKeyId, serialNumber);
return false;
}
}
// 使用证书验签
requireNonNull(certificateProvider);
X509Certificate certificate = certificateProvider.getCertificate(serialNumber);
if (certificate == null) {
logger.error(
"Verify the signature and get the WechatPay certificate corresponding to "
"Verify the signature and get the WechatPay certificate or publicKey corresponding to "
+ "serialNumber[{}] is empty.",
serialNumber);
return false;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,8 @@ public RSAVerifier(CertificateProvider provider) {
public RSAVerifier(PublicKey publicKey, String publicKeyId) {
super(SHA256WITHRSA, publicKey, publicKeyId);
}

public RSAVerifier(PublicKey publicKey, String publicKeyId, CertificateProvider provider) {
super(SHA256WITHRSA, publicKey, publicKeyId, provider);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,16 @@
import com.wechat.pay.java.core.cipher.AeadCipher;
import com.wechat.pay.java.core.cipher.RSAVerifier;
import com.wechat.pay.java.core.cipher.Verifier;
import java.security.PublicKey;

public abstract class AbstractNotificationConfig implements NotificationConfig {

public final String signType;
private final String cipherAlgorithm;
private final CertificateProvider certificateProvider;
private final AeadCipher aeadCipher;
private final PublicKey publicKey;
private final String publicKeyId;

protected AbstractNotificationConfig(
String signType,
Expand All @@ -21,6 +24,37 @@ protected AbstractNotificationConfig(
this.cipherAlgorithm = cipherAlgorithm;
this.certificateProvider = certificateProvider;
this.aeadCipher = aeadCipher;
this.publicKey = null;
this.publicKeyId = null;
}

protected AbstractNotificationConfig(
String signType,
String cipherAlgorithm,
PublicKey publicKey,
String publicKeyId,
AeadCipher aeadCipher) {
this.signType = signType;
this.cipherAlgorithm = cipherAlgorithm;
this.publicKey = publicKey;
this.publicKeyId = publicKeyId;
this.aeadCipher = aeadCipher;
this.certificateProvider = null;
}

protected AbstractNotificationConfig(
String signType,
String cipherAlgorithm,
CertificateProvider certificateProvider,
PublicKey publicKey,
String publicKeyId,
AeadCipher aeadCipher) {
this.signType = signType;
this.cipherAlgorithm = cipherAlgorithm;
this.publicKey = publicKey;
this.publicKeyId = publicKeyId;
this.aeadCipher = aeadCipher;
this.certificateProvider = certificateProvider;
}

@Override
Expand All @@ -35,6 +69,12 @@ public String getCipherType() {

@Override
public Verifier createVerifier() {
if (publicKey != null && certificateProvider != null) {
return new RSAVerifier(publicKey, publicKeyId, certificateProvider);
}
if (publicKey != null) {
return new RSAVerifier(publicKey, publicKeyId);
}
return new RSAVerifier(certificateProvider);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
package com.wechat.pay.java.core.notification;

/** Notification 常量 */
public final class Constant {
public static final String RSA_SIGN_TYPE = "WECHATPAY2-SHA256-RSA2048";
Expand Down
Loading

0 comments on commit 1259626

Please sign in to comment.