Skip to content

Commit 34cea66

Browse files
committed
binarywang#788 批量修改所有使用字符串的getBytes方法的地方,显式使用utf-8编码,以免某些场景下出问题
1 parent ec5cc69 commit 34cea66

File tree

8 files changed

+72
-73
lines changed

8 files changed

+72
-73
lines changed

weixin-java-common/src/main/java/me/chanjar/weixin/common/util/SignUtils.java

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
11
package me.chanjar.weixin.common.util;
22

3-
import lombok.extern.slf4j.Slf4j;
4-
import org.apache.commons.codec.binary.Hex;
5-
6-
import javax.crypto.Mac;
7-
import javax.crypto.spec.SecretKeySpec;
3+
import java.nio.charset.StandardCharsets;
84
import java.security.InvalidKeyException;
95
import java.security.NoSuchAlgorithmException;
6+
import javax.crypto.Mac;
7+
import javax.crypto.spec.SecretKeySpec;
8+
9+
import org.apache.commons.codec.binary.Hex;
10+
11+
import lombok.extern.slf4j.Slf4j;
1012

1113
/**
1214
* <pre>
@@ -27,9 +29,9 @@ public class SignUtils {
2729
public static String createHmacSha256Sign(String message, String key) {
2830
try {
2931
Mac sha256 = Mac.getInstance("HmacSHA256");
30-
SecretKeySpec secretKeySpec = new SecretKeySpec(key.getBytes(), "HmacSHA256");
32+
SecretKeySpec secretKeySpec = new SecretKeySpec(key.getBytes(StandardCharsets.UTF_8), "HmacSHA256");
3133
sha256.init(secretKeySpec);
32-
byte[] bytes = sha256.doFinal(message.getBytes());
34+
byte[] bytes = sha256.doFinal(message.getBytes(StandardCharsets.UTF_8));
3335
return Hex.encodeHexString(bytes).toUpperCase();
3436
} catch (NoSuchAlgorithmException | InvalidKeyException e) {
3537
SignUtils.log.error(e.getMessage(), e);

weixin-java-common/src/main/java/me/chanjar/weixin/common/util/crypto/PKCS7Encoder.java

Lines changed: 12 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,22 @@
1-
/**
1+
/*
22
* 对公众平台发送给公众账号的消息加解密示例代码.
33
*
44
* @copyright Copyright (c) 1998-2014 Tencent Inc.
55
*/
66

7-
// ------------------------------------------------------------------------
8-
97
package me.chanjar.weixin.common.util.crypto;
108

119
import java.nio.charset.Charset;
10+
import java.nio.charset.StandardCharsets;
1211
import java.util.Arrays;
1312

1413
/**
15-
* 提供基于PKCS7算法的加解
14+
* 提供基于PKCS7算法的加解.
15+
*
16+
* @author tencent
1617
*/
1718
public class PKCS7Encoder {
18-
19-
private static final Charset CHARSET = Charset.forName("utf-8");
19+
private static final Charset CHARSET = StandardCharsets.UTF_8;
2020
private static final int BLOCK_SIZE = 32;
2121

2222
/**
@@ -28,20 +28,17 @@ public class PKCS7Encoder {
2828
public static byte[] encode(int count) {
2929
// 计算需要填充的位数
3030
int amountToPad = BLOCK_SIZE - (count % BLOCK_SIZE);
31-
if (amountToPad == 0) {
32-
amountToPad = BLOCK_SIZE;
33-
}
3431
// 获得补位所用的字符
3532
char padChr = chr(amountToPad);
36-
String tmp = new String();
33+
StringBuilder tmp = new StringBuilder();
3734
for (int index = 0; index < amountToPad; index++) {
38-
tmp += padChr;
35+
tmp.append(padChr);
3936
}
40-
return tmp.getBytes(CHARSET);
37+
return tmp.toString().getBytes(CHARSET);
4138
}
4239

4340
/**
44-
* 删除解密后明文的补位字符
41+
* 删除解密后明文的补位字符.
4542
*
4643
* @param decrypted 解密后的明文
4744
* @return 删除补位字符后的明文
@@ -55,12 +52,12 @@ public static byte[] decode(byte[] decrypted) {
5552
}
5653

5754
/**
58-
* 将数字转化成ASCII码对应的字符,用于对明文进行补码
55+
* 将数字转化成ASCII码对应的字符,用于对明文进行补码.
5956
*
6057
* @param a 需要转化的数字
6158
* @return 转化得到的字符
6259
*/
63-
public static char chr(int a) {
60+
private static char chr(int a) {
6461
byte target = (byte) (a & 0xFF);
6562
return (char) target;
6663
}

weixin-java-common/src/main/java/me/chanjar/weixin/common/util/crypto/WxCryptUtil.java

Lines changed: 16 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,21 @@
11
package me.chanjar.weixin.common.util.crypto;
22

3-
import org.apache.commons.codec.binary.Base64;
4-
import org.w3c.dom.Document;
5-
import org.w3c.dom.Element;
6-
import org.xml.sax.InputSource;
7-
3+
import java.io.StringReader;
4+
import java.nio.charset.Charset;
5+
import java.nio.charset.StandardCharsets;
6+
import java.util.Arrays;
7+
import java.util.Random;
88
import javax.crypto.Cipher;
99
import javax.crypto.spec.IvParameterSpec;
1010
import javax.crypto.spec.SecretKeySpec;
1111
import javax.xml.parsers.DocumentBuilder;
1212
import javax.xml.parsers.DocumentBuilderFactory;
1313
import javax.xml.parsers.ParserConfigurationException;
14-
import java.io.StringReader;
15-
import java.nio.charset.Charset;
16-
import java.nio.charset.StandardCharsets;
17-
import java.util.Arrays;
18-
import java.util.Random;
14+
15+
import org.apache.commons.codec.binary.Base64;
16+
import org.w3c.dom.Document;
17+
import org.w3c.dom.Element;
18+
import org.xml.sax.InputSource;
1919

2020
/**
2121
* <pre>
@@ -25,6 +25,8 @@
2525
* 需要导入架包commons-codec-1.9(或commons-codec-1.8等其他版本)
2626
* 官方下载地址:http://commons.apache.org/proper/commons-codec/download_codec.cgi
2727
* </pre>
28+
*
29+
* @author Tencent
2830
*/
2931
public class WxCryptUtil {
3032

@@ -164,8 +166,7 @@ protected String encrypt(String randomStr, String plainText) {
164166
ByteGroup byteCollector = new ByteGroup();
165167
byte[] randomStringBytes = randomStr.getBytes(CHARSET);
166168
byte[] plainTextBytes = plainText.getBytes(CHARSET);
167-
byte[] bytesOfSizeInNetworkOrder = number2BytesInNetworkOrder(
168-
plainTextBytes.length);
169+
byte[] bytesOfSizeInNetworkOrder = number2BytesInNetworkOrder(plainTextBytes.length);
169170
byte[] appIdBytes = this.appidOrCorpid.getBytes(CHARSET);
170171

171172
// randomStr + networkBytesOrder + text + appid
@@ -252,7 +253,7 @@ public String decrypt(String cipherText) {
252253
throw new RuntimeException(e);
253254
}
254255

255-
String xmlContent, from_appid;
256+
String xmlContent, fromAppid;
256257
try {
257258
// 去除补位字符
258259
byte[] bytes = PKCS7Encoder.decode(original);
@@ -264,14 +265,14 @@ public String decrypt(String cipherText) {
264265

265266
xmlContent = new String(Arrays.copyOfRange(bytes, 20, 20 + xmlLength),
266267
CHARSET);
267-
from_appid = new String(
268+
fromAppid = new String(
268269
Arrays.copyOfRange(bytes, 20 + xmlLength, bytes.length), CHARSET);
269270
} catch (Exception e) {
270271
throw new RuntimeException(e);
271272
}
272273

273274
// appid不相同的情况
274-
if (!from_appid.equals(this.appidOrCorpid)) {
275+
if (!fromAppid.equals(this.appidOrCorpid)) {
275276
throw new RuntimeException("AppID不正确");
276277
}
277278

weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/URIUtil.java

Lines changed: 13 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
package me.chanjar.weixin.common.util.http;
22

33

4-
import org.apache.commons.lang3.StringUtils;
4+
import java.nio.charset.StandardCharsets;
55

6-
import java.io.UnsupportedEncodingException;
6+
import org.apache.commons.lang3.StringUtils;
77

88
public class URIUtil {
99

@@ -16,27 +16,22 @@ public static String encodeURIComponent(String input) {
1616

1717
int l = input.length();
1818
StringBuilder o = new StringBuilder(l * 3);
19-
try {
20-
for (int i = 0; i < l; i++) {
21-
String e = input.substring(i, i + 1);
22-
if (ALLOWED_CHARS.indexOf(e) == -1) {
23-
byte[] b = e.getBytes("utf-8");
24-
o.append(getHex(b));
25-
continue;
26-
}
27-
o.append(e);
19+
for (int i = 0; i < l; i++) {
20+
String e = input.substring(i, i + 1);
21+
if (!ALLOWED_CHARS.contains(e)) {
22+
byte[] b = e.getBytes(StandardCharsets.UTF_8);
23+
o.append(getHex(b));
24+
continue;
2825
}
29-
return o.toString();
30-
} catch (UnsupportedEncodingException e) {
31-
e.printStackTrace();
26+
o.append(e);
3227
}
33-
return input;
28+
return o.toString();
3429
}
3530

36-
private static String getHex(byte buf[]) {
31+
private static String getHex(byte[] buf) {
3732
StringBuilder o = new StringBuilder(buf.length * 3);
38-
for (int i = 0; i < buf.length; i++) {
39-
int n = buf[i] & 0xff;
33+
for (byte aBuf : buf) {
34+
int n = aBuf & 0xff;
4035
o.append("%");
4136
if (n < 0x10) {
4237
o.append("0");

weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/notify/WxPayRefundNotifyResult.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package com.github.binarywang.wxpay.bean.notify;
22

33
import java.io.Serializable;
4+
import java.nio.charset.StandardCharsets;
45
import javax.crypto.Cipher;
56
import javax.crypto.spec.SecretKeySpec;
67

@@ -48,7 +49,7 @@ public static WxPayRefundNotifyResult fromXML(String xmlString, String mchKey) t
4849
String reqInfoString = result.getReqInfoString();
4950
try {
5051
final String keyMd5String = DigestUtils.md5Hex(mchKey).toLowerCase();
51-
SecretKeySpec key = new SecretKeySpec(keyMd5String.getBytes(), "AES");
52+
SecretKeySpec key = new SecretKeySpec(keyMd5String.getBytes(StandardCharsets.UTF_8), "AES");
5253

5354
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
5455
cipher.init(Cipher.DECRYPT_MODE, key);

weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/BaseWxPayResult.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import java.io.IOException;
55
import java.io.Serializable;
66
import java.math.BigDecimal;
7+
import java.nio.charset.StandardCharsets;
78
import java.util.List;
89
import java.util.Map;
910
import javax.xml.parsers.DocumentBuilderFactory;
@@ -192,7 +193,7 @@ private Document getXmlDoc() {
192193
this.xmlDoc = DocumentBuilderFactory
193194
.newInstance()
194195
.newDocumentBuilder()
195-
.parse(new ByteArrayInputStream(this.xmlString.getBytes("UTF-8")));
196+
.parse(new ByteArrayInputStream(this.xmlString.getBytes(StandardCharsets.UTF_8)));
196197
return xmlDoc;
197198
} catch (SAXException | IOException | ParserConfigurationException e) {
198199
throw new RuntimeException("非法的xml文本内容:" + this.xmlString);

weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/EntPayServiceImpl.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import java.io.File;
44
import java.io.FileReader;
55
import java.io.IOException;
6+
import java.nio.charset.StandardCharsets;
67
import java.nio.file.Files;
78
import java.nio.file.Path;
89
import java.security.PublicKey;
@@ -126,7 +127,7 @@ private String encryptRSA(File publicKeyFile, String srcString) throws WxPayExce
126127
.getPublicKey((SubjectPublicKeyInfo) reader.readObject());
127128

128129
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
129-
byte[] encrypt = cipher.doFinal(srcString.getBytes());
130+
byte[] encrypt = cipher.doFinal(srcString.getBytes(StandardCharsets.UTF_8));
130131
return Base64.encodeBase64String(encrypt);
131132
}
132133
} catch (Exception e) {
@@ -138,7 +139,7 @@ private File buildPublicKeyFile() throws WxPayException {
138139
try {
139140
String publicKeyStr = this.getPublicKey();
140141
Path tmpFile = Files.createTempFile("payToBank", ".pem");
141-
Files.write(tmpFile, publicKeyStr.getBytes());
142+
Files.write(tmpFile, publicKeyStr.getBytes(StandardCharsets.UTF_8));
142143
return tmpFile.toFile();
143144
} catch (Exception e) {
144145
throw new WxPayException("生成加密公钥文件时发生异常", e);
@@ -162,7 +163,7 @@ public static void main(String[] args) throws WxPayException, IOException {
162163
"p7kM7BoaY2goFgYAe4DsI8Fh33dCOiKyVwIDAQAB\n" +
163164
"-----END RSA PUBLIC KEY-----";
164165
Path tmpFile = Files.createTempFile("payToBank", ".pem");
165-
Files.write(tmpFile, key.getBytes());
166+
Files.write(tmpFile, key.getBytes(StandardCharsets.UTF_8));
166167
System.out.println(new EntPayServiceImpl(null).encryptRSA(tmpFile.toFile(), "111111"));
167168
}
168169

weixin-java-pay/src/test/java/com/github/binarywang/wxpay/bean/notify/WxPayRefundNotifyResultTest.java

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,20 @@
11
package com.github.binarywang.wxpay.bean.notify;
22

3-
import com.github.binarywang.wxpay.config.WxPayConfig;
4-
import com.github.binarywang.wxpay.exception.WxPayException;
5-
import com.github.binarywang.wxpay.testbase.ApiTestModule;
6-
import org.apache.commons.codec.binary.Base64;
7-
import org.testng.annotations.Guice;
8-
import org.testng.annotations.Test;
9-
3+
import java.math.BigInteger;
4+
import java.nio.charset.StandardCharsets;
5+
import java.security.MessageDigest;
106
import javax.crypto.Cipher;
117
import javax.crypto.spec.SecretKeySpec;
128
import javax.inject.Inject;
13-
import java.math.BigInteger;
14-
import java.security.MessageDigest;
159

16-
import static org.testng.Assert.assertNotNull;
10+
import org.apache.commons.codec.binary.Base64;
11+
import org.testng.annotations.*;
12+
13+
import com.github.binarywang.wxpay.config.WxPayConfig;
14+
import com.github.binarywang.wxpay.exception.WxPayException;
15+
import com.github.binarywang.wxpay.testbase.ApiTestModule;
16+
17+
import static org.testng.Assert.*;
1718

1819
/**
1920
* <pre>
@@ -71,10 +72,10 @@ public void encodeReqInfo() throws Exception {
7172

7273
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
7374
final MessageDigest md5 = MessageDigest.getInstance("MD5");
74-
md5.update(this.wxPayConfig.getMchKey().getBytes());
75+
md5.update(this.wxPayConfig.getMchKey().getBytes(StandardCharsets.UTF_8));
7576
final String keyMd5String = new BigInteger(1, md5.digest()).toString(16).toLowerCase();
76-
SecretKeySpec key = new SecretKeySpec(keyMd5String.getBytes(), "AES");
77+
SecretKeySpec key = new SecretKeySpec(keyMd5String.getBytes(StandardCharsets.UTF_8), "AES");
7778
cipher.init(Cipher.ENCRYPT_MODE, key);
78-
System.out.println(Base64.encodeBase64String(cipher.doFinal(xml.getBytes())));
79+
System.out.println(Base64.encodeBase64String(cipher.doFinal(xml.getBytes(StandardCharsets.UTF_8))));
7980
}
8081
}

0 commit comments

Comments
 (0)