美文网首页
签名验证不通过

签名验证不通过

作者: 书上有人说 | 来源:发表于2018-12-13 17:20 被阅读0次

    先上代码

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

    相关文章

      网友评论

          本文标题:签名验证不通过

          本文链接:https://www.haomeiwen.com/subject/xcpbhqtx.html