签名验证不通过

先上代码

/**
    * 验证数字签名函数入口
    * @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默认的字符集。这个可以从百度找下。

你可能感兴趣的:(签名验证不通过)