1
0
mirror of synced 2025-12-15 11:41:42 +08:00

Compare commits

..

2 Commits

Author SHA1 Message Date
copilot-swe-agent[bot]
fc129b987e Fix AES key charset encoding issue in WxPay decryptToString method
Co-authored-by: binarywang <1343140+binarywang@users.noreply.github.com>
2025-09-22 16:36:43 +00:00
copilot-swe-agent[bot]
532f405c76 Initial plan 2025-09-22 16:27:01 +00:00
3 changed files with 4 additions and 128 deletions

View File

@@ -29,7 +29,6 @@ import org.apache.http.ssl.SSLContexts;
import javax.net.ssl.SSLContext;
import java.io.*;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.security.KeyStore;
import java.security.PrivateKey;
import java.security.PublicKey;
@@ -432,14 +431,7 @@ public class WxPayConfig {
}
if (StringUtils.isNotEmpty(configString)) {
// 判断是否为PEM格式的字符串包含-----BEGIN和-----END标记
if (configString.contains("-----BEGIN") && configString.contains("-----END")) {
// PEM格式直接转为字节流让PemUtils处理
configContent = configString.getBytes(StandardCharsets.UTF_8);
} else {
// 纯Base64格式需要先解码
configContent = Base64.getDecoder().decode(configString);
}
configContent = Base64.getDecoder().decode(configString);
return new ByteArrayInputStream(configContent);
}

View File

@@ -80,11 +80,11 @@ public class AesUtils {
try {
Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
SecretKeySpec key = new SecretKeySpec(apiV3Key.getBytes(), "AES");
GCMParameterSpec spec = new GCMParameterSpec(TAG_LENGTH_BIT, nonce.getBytes());
SecretKeySpec key = new SecretKeySpec(apiV3Key.getBytes(StandardCharsets.UTF_8), "AES");
GCMParameterSpec spec = new GCMParameterSpec(TAG_LENGTH_BIT, nonce.getBytes(StandardCharsets.UTF_8));
cipher.init(Cipher.DECRYPT_MODE, key, spec);
cipher.updateAAD(associatedData.getBytes());
cipher.updateAAD(associatedData.getBytes(StandardCharsets.UTF_8));
return new String(cipher.doFinal(Base64.getDecoder().decode(ciphertext)), StandardCharsets.UTF_8);
} catch (NoSuchAlgorithmException | NoSuchPaddingException e) {

View File

@@ -1,116 +0,0 @@
package com.github.binarywang.wxpay.config;
import com.github.binarywang.wxpay.exception.WxPayException;
import org.testng.annotations.Test;
import static org.testng.Assert.*;
/**
* Test cases for private key format handling in WxPayConfig
*/
public class WxPayConfigPrivateKeyTest {
@Test
public void testPrivateKeyStringFormat_PemFormat() {
WxPayConfig config = new WxPayConfig();
// Set minimal required configuration
config.setMchId("1234567890");
config.setApiV3Key("test-api-v3-key-32-characters-long");
config.setCertSerialNo("test-serial-number");
// Test with PEM format private key string that would previously fail
String pemKey = "-----BEGIN PRIVATE KEY-----\n" +
"MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQC2pK3buBufh8Vo\n" +
"X4sfYbZ5CcPeGMnVQTGmj0b6\n" +
"-----END PRIVATE KEY-----";
config.setPrivateKeyString(pemKey);
// This should not throw a "无效的密钥格式" exception immediately
// The actual key validation will happen during HTTP client initialization
// but at least the format parsing should not fail
try {
// Try to initialize API V3 HTTP client - this might fail for other reasons
// (like invalid key content) but should not fail due to format parsing
config.initApiV3HttpClient();
// If we get here without InvalidKeySpecException, the format detection worked
} catch (WxPayException e) {
// Check that it's not the specific "无效的密钥格式" error from PemUtils
if (e.getCause() != null &&
e.getCause().getMessage() != null &&
e.getCause().getMessage().contains("无效的密钥格式")) {
fail("Private key format detection failed - PEM format was not handled correctly: " + e.getMessage());
}
// Other exceptions are acceptable for this test since we're using a dummy key
} catch (Exception e) {
// Check for the specific InvalidKeySpecException that indicates format problems
if (e.getCause() != null &&
e.getCause().getMessage() != null &&
e.getCause().getMessage().contains("无效的密钥格式")) {
fail("Private key format detection failed - PEM format was not handled correctly: " + e.getMessage());
}
// Other exceptions are acceptable for this test since we're using a dummy key
}
}
@Test
public void testPrivateKeyStringFormat_EmptyString() {
WxPayConfig config = new WxPayConfig();
// Test with empty string - should not cause format errors
config.setPrivateKeyString("");
// This should handle empty strings gracefully
// No assertion needed, just ensuring no exceptions during object creation
assertNotNull(config);
}
@Test
public void testPrivateKeyStringFormat_NullString() {
WxPayConfig config = new WxPayConfig();
// Test with null string - should not cause format errors
config.setPrivateKeyString(null);
// This should handle null strings gracefully
assertNotNull(config);
}
@Test
public void testPrivateCertStringFormat_PemFormat() {
WxPayConfig config = new WxPayConfig();
// Set minimal required configuration
config.setMchId("1234567890");
config.setApiV3Key("test-api-v3-key-32-characters-long");
// Test with PEM format certificate string that would previously fail
String pemCert = "-----BEGIN CERTIFICATE-----\n" +
"MIICdTCCAd4CAQAwDQYJKoZIhvcNAQEFBQAwRTELMAkGA1UEBhMCQVUxEzARBgNV\n" +
"BAsKClRlc3QgQ2VydCBEYXRhMRswGQYDVQQDDBJUZXN0IENlcnRpZmljYXRlQ0Ew\n" +
"-----END CERTIFICATE-----";
config.setPrivateCertString(pemCert);
// This should not throw a format parsing exception immediately
// The actual certificate validation will happen during HTTP client initialization
// but at least the format parsing should not fail
try {
// Try to initialize API V3 HTTP client - this might fail for other reasons
// (like invalid cert content) but should not fail due to format parsing
config.initApiV3HttpClient();
// If we get here without Base64 decoding issues, the format detection worked
} catch (Exception e) {
// Check that it's not the specific Base64 decoding error
if (e.getCause() != null &&
e.getCause().getMessage() != null &&
e.getCause().getMessage().contains("Illegal base64 character")) {
fail("Certificate format detection failed - PEM format was not handled correctly: " + e.getMessage());
}
// Other exceptions are acceptable for this test since we're using a dummy cert
}
}
}