Skip to content

Commit 66c0d34

Browse files
authored
新增加解密方法传入transformation (#136)
1 parent ab2c2a4 commit 66c0d34

File tree

3 files changed

+113
-4
lines changed

3 files changed

+113
-4
lines changed

src/main/java/com/wechat/pay/contrib/apache/httpclient/util/PemUtil.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,4 +66,5 @@ public static X509Certificate loadCertificate(InputStream inputStream) {
6666
throw new RuntimeException("无效的证书", e);
6767
}
6868
}
69+
6970
}

src/main/java/com/wechat/pay/contrib/apache/httpclient/util/RsaCryptoUtil.java

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,12 @@ public class RsaCryptoUtil {
1919
private static final String TRANSFORMATION = "RSA/ECB/OAEPWithSHA-1AndMGF1Padding";
2020

2121
public static String encryptOAEP(String message, X509Certificate certificate) throws IllegalBlockSizeException {
22+
return encrypt(message, certificate, TRANSFORMATION);
23+
}
24+
25+
public static String encrypt(String message, X509Certificate certificate, String transformation) throws IllegalBlockSizeException {
2226
try {
23-
Cipher cipher = Cipher.getInstance(TRANSFORMATION);
27+
Cipher cipher = Cipher.getInstance(transformation);
2428
cipher.init(Cipher.ENCRYPT_MODE, certificate.getPublicKey());
2529
byte[] data = message.getBytes(StandardCharsets.UTF_8);
2630
byte[] ciphertext = cipher.doFinal(data);
@@ -36,8 +40,12 @@ public static String encryptOAEP(String message, X509Certificate certificate) th
3640
}
3741

3842
public static String decryptOAEP(String ciphertext, PrivateKey privateKey) throws BadPaddingException {
43+
return decrypt(ciphertext, privateKey, TRANSFORMATION);
44+
}
45+
46+
public static String decrypt(String ciphertext, PrivateKey privateKey, String transformation) throws BadPaddingException {
3947
try {
40-
Cipher cipher = Cipher.getInstance(TRANSFORMATION);
48+
Cipher cipher = Cipher.getInstance(transformation);
4149
cipher.init(Cipher.DECRYPT_MODE, privateKey);
4250
byte[] data = Base64.getDecoder().decode(ciphertext);
4351
return new String(cipher.doFinal(data), StandardCharsets.UTF_8);

src/test/java/com/wechat/pay/contrib/apache/httpclient/RsaCryptoTest.java

Lines changed: 102 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import static org.apache.http.HttpStatus.SC_BAD_REQUEST;
66
import static org.apache.http.HttpStatus.SC_UNAUTHORIZED;
77
import static org.apache.http.entity.ContentType.APPLICATION_JSON;
8+
import static org.junit.Assert.assertEquals;
89
import static org.junit.Assert.assertTrue;
910

1011
import com.wechat.pay.contrib.apache.httpclient.auth.PrivateKeySigner;
@@ -14,9 +15,13 @@
1415
import com.wechat.pay.contrib.apache.httpclient.cert.CertificatesManager;
1516
import com.wechat.pay.contrib.apache.httpclient.util.PemUtil;
1617
import com.wechat.pay.contrib.apache.httpclient.util.RsaCryptoUtil;
18+
19+
import java.io.ByteArrayInputStream;
1720
import java.io.IOException;
1821
import java.nio.charset.StandardCharsets;
1922
import java.security.PrivateKey;
23+
import java.util.Base64;
24+
2025
import org.apache.http.HttpEntity;
2126
import org.apache.http.client.methods.CloseableHttpResponse;
2227
import org.apache.http.client.methods.HttpPost;
@@ -27,15 +32,66 @@
2732
import org.junit.Before;
2833
import org.junit.Test;
2934

35+
import javax.crypto.BadPaddingException;
36+
import javax.crypto.Cipher;
37+
import javax.crypto.IllegalBlockSizeException;
38+
import javax.management.PersistentMBean;
39+
3040
public class RsaCryptoTest {
3141

3242
private static final String mchId = ""; // 商户号
3343
private static final String mchSerialNo = ""; // 商户证书序列号
3444
private static final String apiV3Key = ""; // API V3密钥
35-
private static final String privateKey = "-----BEGIN PRIVATE KEY-----\n"
36-
+ "-----END PRIVATE KEY-----\n"; // 商户API V3私钥
45+
private static final String privateKey = ""; // 商户API V3私钥
3746
private static final String wechatPaySerial = ""; // 平台证书序列号
3847

48+
private static final String certForEncrypt = "-----BEGIN CERTIFICATE-----\n" +
49+
"MIIC4jCCAcoCCQCtzUA6NgI3njANBgkqhkiG9w0BAQsFADAzMQswCQYDVQQGEwJD\n" +
50+
"TjERMA8GA1UECAwIc2hhbmdoYWkxETAPBgNVBAcMCHNoYW5naGFpMB4XDTIyMDUw\n" +
51+
"OTIwMjE1NloXDTIzMDUwOTIwMjE1NlowMzELMAkGA1UEBhMCQ04xETAPBgNVBAgM\n" +
52+
"CHNoYW5naGFpMREwDwYDVQQHDAhzaGFuZ2hhaTCCASIwDQYJKoZIhvcNAQEBBQAD\n" +
53+
"ggEPADCCAQoCggEBALMGZq4BnKaX/VXeg9rLkpE7LqQ5uxgIfKMKSvLzCHA3ZfOR\n" +
54+
"p9fl8DtD0/svTUJ0JNv/pFRjfNEmlzqSmAW922yBc4uGkDdqrgHmt4/fqsOXcdLt\n" +
55+
"foL5txTdgYutq/127HOhxwixAlJA0PHk6QMuLmG4GN+dwQHWAtQROufgupXoPe6y\n" +
56+
"B+w4y3GaCLXIoqgHJQDePFy4sYkNAeSlHFvomPz4RAivPemEiTh2AmJ+RTZa3qT7\n" +
57+
"8ZzJNqIM0UKHgcPSsMGTzchC7sV9WIDbQZseflz2ZDJIepJeGq/4TSIXBcyd1yUY\n" +
58+
"GWfQRb/l640C3Izj3nililXWFLCWW5dKBnUGqdMCAwEAATANBgkqhkiG9w0BAQsF\n" +
59+
"AAOCAQEAo4LkShFg+btEjQUxuShD7SQeNh2DDvdCtEQo5IUY7wtgm95fDGgR1QTA\n" +
60+
"9IElN0EpiyvHnPlsjisl8heCL/OnTvrvxJyOp64AiPO6l9j7/nbf9cMHXPOaZODa\n" +
61+
"hS4rdokqUAswRA7wkiK6+hOPw/90+P7EPw6xCNRYTfl2ii5jirisrkc6iOW2nbUd\n" +
62+
"MjFd3gRGBM/ks3oltGbQbTOwntrAb7wy5EYakdZoKix6CQlqZIdbDXJBEgdXPftt\n" +
63+
"80ReqYWTWYyffHCuALMzmFw0fd6gFb/md2oIb13tcKCwiAe1mQmnudRsDH5b5Zps\n" +
64+
"iSuewmex8WO7a4/lc2WWKpSb/8JwNQ==\n" +
65+
"-----END CERTIFICATE-----"; // 用于测试加密功能的证书
66+
private static final String privateKeyForDecrypt = "-----BEGIN PRIVATE KEY-----\n" +
67+
"MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQCzBmauAZyml/1V\n" +
68+
"3oPay5KROy6kObsYCHyjCkry8whwN2XzkafX5fA7Q9P7L01CdCTb/6RUY3zRJpc6\n" +
69+
"kpgFvdtsgXOLhpA3aq4B5reP36rDl3HS7X6C+bcU3YGLrav9duxzoccIsQJSQNDx\n" +
70+
"5OkDLi5huBjfncEB1gLUETrn4LqV6D3usgfsOMtxmgi1yKKoByUA3jxcuLGJDQHk\n" +
71+
"pRxb6Jj8+EQIrz3phIk4dgJifkU2Wt6k+/GcyTaiDNFCh4HD0rDBk83IQu7FfViA\n" +
72+
"20GbHn5c9mQySHqSXhqv+E0iFwXMndclGBln0EW/5euNAtyM4954pYpV1hSwlluX\n" +
73+
"SgZ1BqnTAgMBAAECggEAUjhnYhVFb9GwPQbEAfGq796BblVBUylarLqmb2wk/PzE\n" +
74+
"axgDQQnOyjk9m0g/MH0NDKkdPNCwW5JgtDrtbP2kT/IoMfVsOLdbEW538bDkyY29\n" +
75+
"bgU7LEYpyoBs5cyuh+tdb0HmmlxJV6ODEwVx6s8D6EdXzSOzp/c1N1Zuel5g80V/\n" +
76+
"oE5pTb6XBObrCq4ZmMT5y59pSroZDV+RlYZqYtXeCdni+9jzVb+7AM50wqp3D17M\n" +
77+
"P9OZnYVyiKS9GEM68klXt3dCnp5P80WVLLupin3DODGdkU0kDFWZE+Hw8Xype5iP\n" +
78+
"jgJMZwieOsniveAsIjwtRjh0yZ6xJe47G1JOGppK8QKBgQDuM5eyIJhhwkxbQ1ov\n" +
79+
"PbRQbeHrdWUuWuruggg2BMXI3RQH5yELyysOY7rrxSob0L90ww7QLtvaw4GNAFsV\n" +
80+
"/OpXs1bkn3QD3lCh4jskbe816iHnYpLKcdkewcIove3wVAaT5/VYeyW9R1mXZLFr\n" +
81+
"sXAYef1Fys1yg6eM8GuiFGu7yQKBgQDAZtue4T1JNR4IEMXU4wRUmU2itu+7A2W6\n" +
82+
"GskyKaXNvKt0g8ZawDIYEl+B35mRJ29O+8rGKIpqqMEfy+En9/aphouMu9S0cFfS\n" +
83+
"n/H1M1B9cfscqyXnS/Ed1kCC9SlfkRXuJ+HhZQ7Zt95vHwf2ugYeg6GDtghC4JHA\n" +
84+
"NIdntlOOuwKBgQCi8IvN/1n9VUmiDBp+wji7485soGtMIEkgSbaQLQeWdRQkq8gB\n" +
85+
"J0MWnsXYTZCWYl704hEZ+1PM+3t9Fkc4bT9oKndAAIr9sm95rSVDsCe3u6bhfp5m\n" +
86+
"+SXKUkQcVn+SrAer2ToNAoA4T7xLQUfUIRZKx/embCnJMaHFWRhnUIy5cQKBgQCG\n" +
87+
"tHz3E8OQybuo8fVQQ1D42gxc66+UQ6CpV6+di0Mmc/2mqcvqJb3s1JBBoYcm9XEc\n" +
88+
"33Tsn92pJ1VvKZMOJLFxp110vt0BJ9aVBJ6mibLE4VRqkfkLo0PBHAw2o+a/nhi4\n" +
89+
"kPu4jsSC8hStwBAXUc6O9qHSUVQfXpMs+poCpsiBmQKBgQDO+B/xX6V6GQIrPgiF\n" +
90+
"nKpSi566ouXcNxiMIb8w7nu4r/0mJ91roVD0N1TyCOVKTrY/R/4KsQV4pp2bQfV7\n" +
91+
"3tYnrSVgBhPHfWkWQG+7sUXWRR5/c8jszKM+no/bsxmqsAJdK2ih/crHD7XrGgXL\n" +
92+
"XWU1WCYDnWGKm3byXlLY1tFO/Q==\n" +
93+
"-----END PRIVATE KEY-----"; // 用于测试解密功能的私钥
94+
3995
private CloseableHttpClient httpClient;
4096
private CertificatesManager certificatesManager;
4197
private Verifier verifier;
@@ -69,6 +125,50 @@ public void encryptTest() throws Exception {
69125
System.out.println("ciphertext: " + ciphertext);
70126
}
71127

128+
@Test
129+
public void encryptWithPkcs1TransformationTest() throws Exception {
130+
String text = "helloworld";
131+
String transformation = "RSA/ECB/PKCS1Padding";
132+
String encryptedText = RsaCryptoUtil.encrypt(text, PemUtil.loadCertificate(new ByteArrayInputStream(certForEncrypt.getBytes())), transformation);
133+
//utilize the standard lib to verify the correctness of the encrypted result.
134+
Cipher cipher = Cipher.getInstance(transformation);
135+
cipher.init(Cipher.DECRYPT_MODE, PemUtil.loadPrivateKey(privateKeyForDecrypt));
136+
String secretText = new String((cipher.doFinal(Base64.getDecoder().decode(encryptedText))));
137+
assert(text.equals(secretText));
138+
}
139+
140+
@Test
141+
public void decryptWithPkcs1TransformationTest() throws BadPaddingException {
142+
String encryptedText = "lmkkdBz5CH4Zk6KIEzbyenf+WtKe8nuU9j+t8HonOm4v1OfLRiYhvdcequOSuaz5vjdpX434XjV9Q5LGC8aOC" +
143+
"DZs/8LoyR3m/6JpYa0nkGOh6Le2JvSPNXlSq9HUEoElBJD5KsxbsRoif0kuioBGSKvKB0xwIvVtn+S0H2GYya7TC1L/ddhGhI/yx" +
144+
"ZgS/TI/Ppej3OzNmu0xA5RjpDR4rGAUrLvV7y/aM4mCN6WOaO6YsAnlGoSbK+P1sepeb0sCaJMClqbLE0Eoz2ve9FQ30w1Vgi5F0" +
145+
"2rpDwcZO8EXAkub0L12BN4QWBNK8FaKlS4UZPAGAwutLK6Gylig54Quig==";
146+
String transformation = "RSA/ECB/PKCS1Padding";
147+
assertEquals("helloworld", RsaCryptoUtil.decrypt(encryptedText, PemUtil.loadPrivateKey(privateKeyForDecrypt), transformation));
148+
}
149+
150+
@Test
151+
public void encryptWithOaepTransformationTest() throws Exception {
152+
String text = "helloworld";
153+
String transformation = "RSA/ECB/OAEPWithSHA-1AndMGF1Padding";
154+
String encryptedText = RsaCryptoUtil.encrypt(text, PemUtil.loadCertificate(new ByteArrayInputStream(certForEncrypt.getBytes())), transformation);
155+
//utilize the standard lib to verify the correctness of the encrypted result.
156+
Cipher cipher = Cipher.getInstance(transformation);
157+
cipher.init(Cipher.DECRYPT_MODE, PemUtil.loadPrivateKey(privateKeyForDecrypt));
158+
String secretText = new String((cipher.doFinal(Base64.getDecoder().decode(encryptedText))));
159+
assert(text.equals(secretText));
160+
}
161+
162+
@Test
163+
public void decryptWithOaepTransformationTest() throws BadPaddingException {
164+
String encryptedText = "FJ8/0ubyxnMZ0GN2YEUgJgDVPCwMrsTKuLFxycI3jvOAcVTDEEermn2F7+cUtmCYvD2TkHUMHvWeJB6/nSPBD" +
165+
"eGuxA4bCr584h2w9bRvVrwtQlnv1HpF2WRdGAuPcgrQcZvMpiH2ysxgPrGPMs9WOr8etxf1FifI0DkMb6w7wl2BDPPK+RfRdZq7T" +
166+
"9KBtH2IllVTLUbRSqDGIctgIxB7RMqd3s/eK0p2Qjui8AVgP4j5Spq6JjITgKn0VDOO4JwzU8Zl++BwveoJMkTN150XF5ot+ruZv" +
167+
"lNgjP1Hez0/rFxY7gQvxrSDwgL5A9up6JRI741psfs/3HrzBJOBdvO73A==";
168+
String transformation = "RSA/ECB/OAEPWithSHA-1AndMGF1Padding";
169+
assertEquals("helloworld", RsaCryptoUtil.decrypt(encryptedText, PemUtil.loadPrivateKey(privateKeyForDecrypt), transformation));
170+
}
171+
72172
@Test
73173
public void postEncryptDataTest() throws Exception {
74174
HttpPost httpPost = new HttpPost("https://api.mch.weixin.qq.com/v3/smartguide/guides");

0 commit comments

Comments
 (0)