javax.crypto.badpaddingexception:解密错误-无法从文件中解密多个块

h22fl7wq  于 2021-07-06  发布在  Java
关注(0)|答案(0)|浏览(194)

希望有人能给我指出正确的方向。
我对加密不是特别熟悉(用java或其他语言),但我说过我会帮助某人完成一项任务,他们指定使用rsa加密/解密。
为了让自己熟悉要完成的工作,我准备了一个小示例程序:
生成6个随机数,并将它们放入逗号分隔的字符串中
加密数字序列
将加密的数字序列附加到一个文件-如果程序运行多次,同一个文件可以被多次写入
读取加密文件-应获取所有已写入的序列
解密每个序列并打印出逗号分隔字符串的集合
在第一次尝试时,也就是说,当第一个序列被写入一个空文件,并且返回正确的数字序列时,这种方法可以很好地工作。
当文件包含多个加密序列时,这会导致 decrypt 和一个 BadPaddingException . 在这一点上我已经做了一步,每一个 byte[] (代表一个加密序列)要解密的是128字节,所以不是不规则的字节数导致了问题。
我知道rsa不再是推荐的方法,但这是我必须考虑的规范。我也知道有很多关于rsa和badpaddingexception的问题,但是我还没有遇到一个能解决这个问题的问题。
我的示例代码如下:

public class EncryptDecrypt {

    private static Cipher cipher;
    private static KeyPair keyPair;

    public static void main(String[] args)
    {
        String[] numbers = getNumbers();
        String numbersStr = String.join(", ", numbers);
        System.out.println("Generated: " + numbersStr + ", NumBytes: " + numbersStr.getBytes().length);

        byte[] encryptedNumbers = encrypt(numbersStr);
        System.out.println("Encrypted: " + encryptedNumbers.toString() + ", NumBytes: " + encryptedNumbers.length);

        writeToFile(encryptedNumbers);
        System.out.println("Encrypted numbers written to data.txt");

        ArrayList<byte[]> encryptedData = readFromFile();
        System.out.println("Encrypted numbers read from data.txt, NumSequences: " + encryptedData.size());

        ArrayList<String> decryptedSequences = decrypt(encryptedData);
        for (int i = 0; i < decryptedSequences.size(); i++)
        {
            String sequence = decryptedSequences.get(i);
            System.out.println("Sequence " + i + ": " + sequence);
        }
    }

    private static String[] getNumbers()
    {
        String[] numbers = new String[6];

        int min = 1;
        int max = 60;

        for (int i = 0; i < numbers.length; i++)
        {
            double number = (Math.random() * (max - min) + min);
            numbers[i] = number >= 10 ? Integer.toString((int) number) : "0" + Integer.toString((int) number);
        }

        return numbers;
    }

    private static byte[] encrypt(String data)
    {
        try {
            KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
            keyPairGenerator.initialize(2048);
            keyPair = keyPairGenerator.generateKeyPair();
            PublicKey publicKey = keyPair.getPublic();
            cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");

            cipher.init(Cipher.ENCRYPT_MODE, publicKey);
            cipher.update(data.getBytes());
            byte[] encrypted = cipher.doFinal();

            return encrypted;
        } catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | IllegalBlockSizeException | BadPaddingException ex) {
            Logger.getLogger(EncryptDecrypt.class.getName()).log(Level.SEVERE, null, ex);
        }

        return null;
    }

    private static void writeToFile(byte[] data)
    {
        FileOutputStream fileOut = null;
        try {
            File file = new File("data.txt");
            file.createNewFile();
            fileOut = new FileOutputStream(file, true);

            fileOut.write(data);
            fileOut.flush();
            fileOut.close();
        } catch (FileNotFoundException ex) {
            Logger.getLogger(EncryptDecrypt.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IOException ex) {
            Logger.getLogger(EncryptDecrypt.class.getName()).log(Level.SEVERE, null, ex);
        } finally {
            try {
                fileOut.close();
            } catch (IOException ex) {
                Logger.getLogger(EncryptDecrypt.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
    }

    private static ArrayList<byte[]> readFromFile()
    {
        File file = new File("data.txt");
        if (file.exists())
        {
            try {
                ArrayList<byte[]> encryptedSequences = new ArrayList<>();
                FileInputStream fileIn = new FileInputStream(file);
                int blockSize = 128;
                int numBlocks = fileIn.available() / blockSize;

                for (int i = 0; i < numBlocks; i++)
                {
                    byte[] encryptedSequence = new byte[blockSize];
                    fileIn.read(encryptedSequence);

                    encryptedSequences.add(encryptedSequence);
                }

                fileIn.close();

                return encryptedSequences;
            } catch (FileNotFoundException ex) {
                Logger.getLogger(EncryptDecrypt.class.getName()).log(Level.SEVERE, null, ex);
            } catch (IOException ex) {
                Logger.getLogger(EncryptDecrypt.class.getName()).log(Level.SEVERE, null, ex);
            }
        }

        return null;
    }

    private static ArrayList<String> decrypt(ArrayList<byte[]> data)
    {
        try {
            cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
            PrivateKey privateKey = keyPair.getPrivate();

            cipher.init(Cipher.DECRYPT_MODE, privateKey);

            ArrayList<String> decryptedStrings = new ArrayList<>();

            for (byte[] sequence : data)
            {
                byte[] decryptedBytes = cipher.doFinal(sequence);
                String decryptedString = new String(decryptedBytes);
                decryptedStrings.add(decryptedString);
            }

            return decryptedStrings;
        } catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | IllegalBlockSizeException | BadPaddingException ex) {
            Logger.getLogger(EncryptDecrypt.class.getName()).log(Level.SEVERE, null, ex);
        }

        return null;
    }
}

如果有人能发现这有什么问题,我真的很感激!
谢谢

暂无答案!

目前还没有任何答案,快来回答吧!

相关问题