• RSA解密报错 javax.crypto.BadPaddingException: Decryption error


      最近在写关于RSA加解密的方法,遇到一个很奇怪的问题,本地测试的时候没有问题,但是一到线上的时候就会报错,下面展示一下本地测试的主要方法:

     static void test() throws Exception {
            System.err.println("公钥加密——私钥解密");
            String uuid = "c804609f89b542a3888d00405ee13dbc";
            String cpuid = SerialNumberUtil.getCPUSerial().toUpperCase().replace(" ", "");
            String mainboard = SerialNumberUtil.getMotherboardSN().toUpperCase().replace(" ", "");
    //        String disk = SerialNumberUtil.getHardDiskSN("c").toUpperCase().replace(" ", "");
            String mac = SerialNumberUtil.getMac().toUpperCase().replace(" ", "");
    
            String registerTime = DateUtil.getCurrentTime();
            StringBuilder strBuilder = new StringBuilder();
            strBuilder.append("UUID").append("=").append(uuid).append(";");
            strBuilder.append("CPU").append("=").append(cpuid).append(";").append("Mainboard").append("=").append(mainboard).append(";");
            strBuilder.append("MAC").append("=").append(mac).append(";").append("registerTime").append("=").append(registerTime);
            byte[] data = strBuilder.toString().getBytes();
            byte[] encodedData = RSAUtil.encryptByPublicKey(data, publicKey);
    
            byte[] decodedData = RSAUtil.decryptByPrivateKey(encodedData, privateKey);
            String target = new String(decodedData);
            System.out.println("解密后文字: 
    " + target);
        }

    本地测试一切都是ok,但是线上测试的时候出现了错误: javax.crypto.BadPaddingException: Decryption error。经过debug后发现是因为数组转成字符串的时候报错,于是我就在本地进行了测试“:

    static void test() throws Exception {
            System.err.println("公钥加密——私钥解密");
            String uuid = "c804609f89b542a3888d00405ee13dbc";
            String cpuid = SerialNumberUtil.getCPUSerial().toUpperCase().replace(" ", "");
            String mainboard = SerialNumberUtil.getMotherboardSN().toUpperCase().replace(" ", "");
    //        String disk = SerialNumberUtil.getHardDiskSN("c").toUpperCase().replace(" ", "");
            String mac = SerialNumberUtil.getMac().toUpperCase().replace(" ", "");
    
            String registerTime = DateUtil.getCurrentTime();
            StringBuilder strBuilder = new StringBuilder();
            strBuilder.append("UUID").append("=").append(uuid).append(";");
            strBuilder.append("CPU").append("=").append(cpuid).append(";").append("Mainboard").append("=").append(mainboard).append(";");
            strBuilder.append("MAC").append("=").append(mac).append(";").append("registerTime").append("=").append(registerTime);
            byte[] data = strBuilder.toString().getBytes();
            byte[] encodedData = RSAUtil.encryptByPublicKey(data, publicKey);
            System.out.println("***********************************" + encodedData.length);
            String encodeData = new String(encodedData);
            System.out.println("加密后文字:
    " + encodeData);
            byte[] dataq = encodeData.getBytes();
            System.out.println("***********************************" + dataq.length);
            byte[] decodedData = RSAUtil.decryptByPrivateKey(dataq, privateKey);
            String target = new String(decodedData);
            System.out.println("解密后文字: 
    " + target);
        }

    主要的报错信息是:

    公钥加密——私钥解密
    v4:127.0.0.1
    v4:192.168.99.137
    ***********************************256
    加密后文字:
    bӷX����)�5��hF2M��5u�2�Y����3)n:f-�H�#���
    �}K"=a9S������L���0ףޟ�ZSD�O�� ��p1ɗ��ߙ��Bh?�@�B�3�u��    $M��.�nףD,��S6Z�(E�>����r��S���=š�����{d��$�IMv��o֘�3|(i���I{�}>�A�_�ܾ��εU��2Lo�NM=��f�l#����7��gCj� ��Q��A��4�b    <�&"�/?��!+
    ***********************************467
    Exception in thread "main" javax.crypto.BadPaddingException: Decryption error
        at sun.security.rsa.RSAPadding.unpadV15(RSAPadding.java:380)
        at sun.security.rsa.RSAPadding.unpad(RSAPadding.java:291)
        at com.sun.crypto.provider.RSACipher.doFinal(RSACipher.java:363)
        at com.sun.crypto.provider.RSACipher.engineDoFinal(RSACipher.java:389)
        at javax.crypto.Cipher.doFinal(Cipher.java:2222)
        at com.hlxj.license.demo.rsa.RSAUtil.decryptByPrivateKey(RSAUtil.java:145)
        at com.hlxj.license.demo.rsa.TestRsa.test(TestRsa.java:56)
        at com.hlxj.license.demo.rsa.TestRsa.main(TestRsa.java:28)

    仔细观察只有我发现我转成String之前的数组长度和转成String之后的数组长度是不一致的。所以就锁定了是因为字符串和数组之间转换的问题。于是我先到转成字符串的时候可能需要加上标识符,然后再根据空格分隔转换回byte数组。如果不加标识符,由于byte值可能是一位到三位,无法知道某一个byte是在哪里结束。当然也可以在转成string时补0。或者转成16进制固定为两位长。

    方法如下:

    static void test() throws Exception {
            System.err.println("公钥加密——私钥解密");
            String uuid = "c804609f89b542a3888d00405ee13dbc";
            String cpuid = SerialNumberUtil.getCPUSerial().toUpperCase().replace(" ", "");
            String mainboard = SerialNumberUtil.getMotherboardSN().toUpperCase().replace(" ", "");
    //        String disk = SerialNumberUtil.getHardDiskSN("c").toUpperCase().replace(" ", "");
            String mac = SerialNumberUtil.getMac().toUpperCase().replace(" ", "");
    
            String registerTime = DateUtil.getCurrentTime();
            StringBuilder strBuilder = new StringBuilder();
            strBuilder.append("UUID").append("=").append(uuid).append(";");
            strBuilder.append("CPU").append("=").append(cpuid).append(";").append("Mainboard").append("=").append(mainboard).append(";");
            strBuilder.append("MAC").append("=").append(mac).append(";").append("registerTime").append("=").append(registerTime);
            byte[] data = strBuilder.toString().getBytes();
            byte[] encodedData = RSAUtil.encryptByPublicKey(data, publicKey);
            System.out.println("***********************************" + encodedData.length);
            String encodeData = bytesToString(encodedData);
            System.out.println("加密后文字:
    " + encodeData);
            byte[] dataq = stringToBytes(encodeData));
            System.out.println("***********************************" + dataq.length);
            byte[] decodedData = RSAUtil.decryptByPrivateKey(encodedData, privateKey);
            String target = new String(decodedData);
            System.out.println("解密后文字: 
    " + target);
        }
    
    protected static String bytesToString(byte[] encrytpByte) {
            String result = "";
            for (Byte bytes : encrytpByte) {
                result += bytes.toString() + " ";
            }
            return result;
        }
    
        protected static byte[] stringToBytes(String data) {
            String[] strArr = data.split(" ");
            int len = strArr.length;
            byte[] clone = new byte[len];
            for (int i = 0; i < len; i++) {
                clone[i] = Byte.parseByte(strArr[i]);
            }
    
            return clone;
        }

    最后得到了想要的结果。

  • 相关阅读:
    代码编写原则
    换个角度看世界
    不使用nib 文件时,需要改变一个view 的大小时,需要为viewcontroller添加loadView方法
    建议:一般地,建议使用xcode 4.3开发app 而不是使用xcode4.5
    iOS 5解决Could not instantiate class named NSLayoutConstraint问题
    访问对象方法比较
    让一个view 或者控件不支持拖拽
    Java Map遍历方式的选择
    Java里多个Map的性能比较(TreeMap、HashMap、ConcurrentSkipListMap)
    java List集合记录 ArrayList和LinkedList的区别
  • 原文地址:https://www.cnblogs.com/daishoucheng/p/10916858.html
Copyright © 2020-2023  润新知