先上代码
/**
* 验证数字签名函数入口
* @param str 待验签明文
* @param signBytes 待验签签名后字节数组
* @param publicKey 验签使用公钥
* @param signAlgorithm 签名算法
* @return 验签是否通过
* @throws ServiceException
*/
public static boolean verifyDigitalSign(String str, byte[] signBytes, PublicKey publicKey, String signAlgorithm) throws ServiceException {
byte[] plainBytes = str.getBytes();
boolean isValid = false;
try {
Signature signature = Signature.getInstance(signAlgorithm);
signature.initVerify(publicKey);
signature.update(plainBytes);
isValid = signature.verify(signBytes);
return isValid;
} catch (NoSuchAlgorithmException e) {
throw new ServiceException(String.format("验证数字签名时没有[%s]此类算法", signAlgorithm));
} catch (InvalidKeyException e) {
throw new ServiceException("验证数字签名时公钥无效");
} catch (SignatureException e) {
throw new ServiceException("验证数字签名时出现异常");
}
}
同样的校验内容,在本地正常,生产正常,但是在测试环境上发现无法校验通过,
差异:获取str时,由
StringBuffer data = new StringBuffer();
if(code==200){
BufferedReader reader = new BufferedReader(
new InputStreamReader(connection.getInputStream()));
String str = "";
while((str = reader.readLine()) != null){
data.append(str);
}
reader.close();
}else{
data.append("远程服务器连接失败,错误代码:").append(code);
}
改成
StringBuffer data = new StringBuffer();
if(code==200){
BufferedReader reader = new BufferedReader(
new InputStreamReader(connection.getInputStream(),"utf-8"));
String str = "";
while((str = reader.readLine()) != null){
data.append(str);
}
reader.close();
}else{
data.append("远程服务器连接失败,错误代码:").append(code);
}
得到的str结果在本地和测试环境也是一样的。但是在调用校验方法时本地通过,测试环境不通过。经最后检查判断,是由于这两个的jdk字符集不一致造成。可以通过Java程序测试jdk的字符集设置。
System.out.println("Default Charset=" + Charset.defaultCharset());
System.out.println("file.encoding=" + System.getProperty("file.encoding"));
System.out.println("Default Charset=" + Charset.defaultCharset());
System.out.println("Default Charset in Use=" + getDefaultCharSet());
本地:
Default Charset=UTF-8
file.encoding=UTF-8
Default Charset=UTF-8
Default Charset in Use=UTF8
测试:
Default Charset=GB18030
file.encoding=GB18030
Default Charset=GB18030
Default Charset in Use=GB18030
解决办法
1、所有需要指定字符集的地方,都指定为统一的字符集。
2、修改jdk默认的字符集。这个可以从百度找下。
网友评论