-
Notifications
You must be signed in to change notification settings - Fork 221
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
31f42ff
commit 167e9c4
Showing
15 changed files
with
383 additions
and
159 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
121 changes: 121 additions & 0 deletions
121
core/src/main/java/com/wechat/pay/java/core/RSAPublicKeyConfig.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,121 @@ | ||
package com.wechat.pay.java.core; | ||
|
||
import static com.wechat.pay.java.core.notification.Constant.AES_CIPHER_ALGORITHM; | ||
import static com.wechat.pay.java.core.notification.Constant.RSA_SIGN_TYPE; | ||
import static java.util.Objects.requireNonNull; | ||
|
||
import com.wechat.pay.java.core.cipher.AeadAesCipher; | ||
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 com.wechat.pay.java.core.notification.NotificationConfig; | ||
import com.wechat.pay.java.core.util.PemUtil; | ||
import java.nio.charset.StandardCharsets; | ||
import java.security.PublicKey; | ||
|
||
/** 使用微信支付平台公钥的RSA配置类。 每次构造都要求传入平台公钥以及平台公钥id,如果使用平台证书建议用RSAAutoCertificateConfig类 */ | ||
public final class RSAPublicKeyConfig extends AbstractRSAConfig implements NotificationConfig { | ||
|
||
private final PublicKey publicKey; | ||
private final AeadCipher aeadCipher; | ||
private final String publicKeyId; | ||
|
||
private RSAPublicKeyConfig(Builder builder) { | ||
super( | ||
builder.merchantId, | ||
builder.privateKey, | ||
builder.merchantSerialNumber, | ||
builder.publicKey, | ||
builder.publicKeyId); | ||
this.publicKey = builder.publicKey; | ||
this.publicKeyId = builder.publicKeyId; | ||
this.aeadCipher = new AeadAesCipher(builder.apiV3Key); | ||
} | ||
|
||
/** | ||
* 获取签名类型 | ||
* | ||
* @return 签名类型 | ||
*/ | ||
@Override | ||
public String getSignType() { | ||
return RSA_SIGN_TYPE; | ||
} | ||
|
||
/** | ||
* 获取认证加解密器类型 | ||
* | ||
* @return 认证加解密器类型 | ||
*/ | ||
@Override | ||
public String getCipherType() { | ||
return AES_CIPHER_ALGORITHM; | ||
} | ||
|
||
/** | ||
* 创建验签器 | ||
* | ||
* @return 验签器 | ||
*/ | ||
@Override | ||
public Verifier createVerifier() { | ||
return new RSAVerifier(publicKey, publicKeyId); | ||
} | ||
|
||
/** | ||
* 创建认证加解密器 | ||
* | ||
* @return 认证加解密器 | ||
*/ | ||
@Override | ||
public AeadCipher createAeadCipher() { | ||
return aeadCipher; | ||
} | ||
|
||
public static class Builder extends AbstractRSAConfigBuilder<Builder> { | ||
protected byte[] apiV3Key; | ||
protected PublicKey publicKey; | ||
protected String publicKeyId; | ||
|
||
public Builder apiV3Key(String apiV3Key) { | ||
this.apiV3Key = apiV3Key.getBytes(StandardCharsets.UTF_8); | ||
return self(); | ||
} | ||
|
||
public Builder publicKey(String publicKey) { | ||
this.publicKey = PemUtil.loadPublicKeyFromString(publicKey); | ||
return self(); | ||
} | ||
|
||
public Builder publicKey(PublicKey publicKey) { | ||
this.publicKey = publicKey; | ||
return self(); | ||
} | ||
|
||
public Builder publicKeyFromPath(String publicKeyPath) { | ||
this.publicKey = PemUtil.loadPublicKeyFromPath(publicKeyPath); | ||
return self(); | ||
} | ||
|
||
public Builder publicKeyId(String publicKeyId) { | ||
this.publicKeyId = publicKeyId; | ||
return self(); | ||
} | ||
|
||
@Override | ||
protected Builder self() { | ||
return this; | ||
} | ||
|
||
public RSAPublicKeyConfig build() { | ||
requireNonNull(merchantId); | ||
requireNonNull(publicKey); | ||
requireNonNull(publicKeyId); | ||
requireNonNull(privateKey); | ||
requireNonNull(apiV3Key); | ||
requireNonNull(merchantSerialNumber); | ||
|
||
return new RSAPublicKeyConfig(this); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
54 changes: 1 addition & 53 deletions
54
core/src/main/java/com/wechat/pay/java/core/certificate/RSACertificateHandler.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,69 +1,17 @@ | ||
package com.wechat.pay.java.core.certificate; | ||
|
||
import com.wechat.pay.java.core.exception.ValidationException; | ||
import com.wechat.pay.java.core.util.PemUtil; | ||
import java.security.cert.*; | ||
import java.util.*; | ||
|
||
final class RSACertificateHandler implements CertificateHandler { | ||
|
||
private static final X509Certificate tenpayCACert = | ||
PemUtil.loadX509FromString( | ||
"-----BEGIN CERTIFICATE-----\n" | ||
+ "MIIEcDCCA1igAwIBAgIUG9QiDlDbwEsGrTl1SYRsAcPo69IwDQYJKoZIhvcNAQEL\n" | ||
+ "BQAwcDELMAkGA1UEBhMCQ04xEzARBgNVBAoMCmlUcnVzQ2hpbmExHDAaBgNVBAsM\n" | ||
+ "E0NoaW5hIFRydXN0IE5ldHdvcmsxLjAsBgNVBAMMJWlUcnVzQ2hpbmEgQ2xhc3Mg\n" | ||
+ "MiBFbnRlcnByaXNlIENBIC0gRzMwHhcNMTcwODA5MDkxNTU1WhcNMzIwODA5MDkx\n" | ||
+ "NTU1WjBeMQswCQYDVQQGEwJDTjETMBEGA1UEChMKVGVucGF5LmNvbTEdMBsGA1UE\n" | ||
+ "CxMUVGVucGF5LmNvbSBDQSBDZW50ZXIxGzAZBgNVBAMTElRlbnBheS5jb20gUm9v\n" | ||
+ "dCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALvnPD6k39BdPYAH\n" | ||
+ "+6lnWPjuHH+2pcmZUf2E8cNFQFNr+ECRZylYV2iKyItCQt3I2/7VIDZl6aR9TE7n\n" | ||
+ "sZrtSmOXCw635QOrq2yF9LTSDotAhf3ER0+216w3age/VzGcNVQpTf6gRCHCuQIk\n" | ||
+ "8pe/oh06JagGvX0wERa+I6NfuG58ZHQY9d6RqLXKQl0Up95v73HDsG487z8k6jcn\n" | ||
+ "qpGngmHQxdWiWRJugqxNRUD+awv2/DUsqGOffPX4jzJ6rLSJSlQXvuniDYxmaiaD\n" | ||
+ "cK0bUbB5aM+1zMwogoHSYxWj/6B+vgcnHQCUrwGdiQR5+F+yRWzy5bO09IzaFgeO\n" | ||
+ "PNPLPOsCAwEAAaOCARIwggEOMBIGA1UdEwEB/wQIMAYBAf8CAQAwDgYDVR0PAQH/\n" | ||
+ "BAQDAgEGMCAGA1UdEQQZMBekFTATMREwDwYDVQQDDAhzd2JlLTI2NjAdBgNVHQ4E\n" | ||
+ "FgQUTFo4GLdm9oHX52HcWnzuL4tui2gwHwYDVR0jBBgwFoAUK1vVxWgI69vN5LA5\n" | ||
+ "MqJf/8dPmEUwRgYDVR0gBD8wPTA7BgoqgRyG7xcBAQECMC0wKwYIKwYBBQUHAgEW\n" | ||
+ "H2h0dHBzOi8vd3d3Lml0cnVzLmNvbS5jbi9jdG5jcHMwPgYDVR0fBDcwNTAzoDGg\n" | ||
+ "L4YtaHR0cDovL3RvcGNhLml0cnVzLmNvbS5jbi9jcmwvaXRydXNjMmNhZzMuY3Js\n" | ||
+ "MA0GCSqGSIb3DQEBCwUAA4IBAQBwZhL/eiOQmMyo1D0IR9mu1DPWl5J3XXhjc4R6\n" | ||
+ "mFgsN/FCeVP9M4U9y2FJH6i5Ha5YCecKGw5pwhA0rjZr/6okWwo22GF+nzI/gQiz\n" | ||
+ "6ugAKs5VjFbeiEb04Ncz4HT8FP1idK3tyCjqCUTkLNt0U3tR7wy26hgOqlT2wCZ9\n" | ||
+ "X4MfT8dUMdt9nCZx4ujN5yZOzaLOCHmzoGDGxgKg91bbu0TG2Yzd2ylhrxxRtFH9\n" | ||
+ "aZ/J1x5UoF7uwhTM8P92DuAldWC1/bX1kciOtQvQEZeAy+9y/1BtFxoBnmDxnqkX\n" | ||
+ "+lirIUYTLDaL7HaLrOLECUlaxZCU/Nkwm3tmqQxtCh+XQBdd\n" | ||
+ "-----END CERTIFICATE-----"); | ||
|
||
private static final Set<TrustAnchor> trustAnchor = | ||
new LinkedHashSet<>(Collections.singletonList(new TrustAnchor(tenpayCACert, null))); | ||
|
||
@Override | ||
public X509Certificate generateCertificate(String certificate) { | ||
return PemUtil.loadX509FromString(certificate); | ||
} | ||
|
||
@Override | ||
public void validateCertPath(X509Certificate certificate) { | ||
try { | ||
PKIXParameters params = new PKIXParameters(trustAnchor); | ||
params.setRevocationEnabled(false); | ||
|
||
List<X509Certificate> certs = new ArrayList<>(); | ||
certs.add(certificate); | ||
|
||
CertificateFactory cf = CertificateFactory.getInstance("X.509"); | ||
CertPath certPath = cf.generateCertPath(certs); | ||
|
||
CertPathValidator validator = CertPathValidator.getInstance("PKIX"); | ||
validator.validate(certPath, params); | ||
} catch (Exception e) { | ||
throw new ValidationException( | ||
String.format( | ||
"certificate[%s] validation failed: %s", | ||
PemUtil.getSerialNumber(certificate), e.getMessage()), | ||
e); | ||
} | ||
// 为防止证书过期导致验签失败,从而影响业务,后续不再验证证书信任链 | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.