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("解密后文字: \r\n" + 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("加密后文字:\r\n" + encodeData);
        byte[] dataq = encodeData.getBytes();
        System.out.println("***********************************" + dataq.length);
        byte[] decodedData = RSAUtil.decryptByPrivateKey(dataq, privateKey);
        String target = new String(decodedData);
        System.out.println("解密后文字: \r\n" + 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("加密后文字:\r\n" + encodeData);
        byte[] dataq = stringToBytes(encodeData));
        System.out.println("***********************************" + dataq.length);
        byte[] decodedData = RSAUtil.decryptByPrivateKey(encodedData, privateKey);
        String target = new String(decodedData);
        System.out.println("解密后文字: \r\n" + 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;
    }

最后得到了想要的結果。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM