0

我正在尝试构建一个压缩的 Java 程序,然后使用 AES 加密对文件进行加密。但是,我在加密过程中收到以下错误:

Exception in thread "main" java.security.NoSuchAlgorithmException: Cannot find any provider supporting PBKDF2WithHmacSHA256
at java.base/javax.crypto.Cipher.getInstance(Cipher.java:574)
at MyJavaProject.zip.encryptFile(zip.java:75)
at MyJavaProject.zip.main(zip.java:58)

我在下面包含了我的代码。它应该压缩我指向的文件,然后对其进行加密,并保存盐和 IV 的字节,以便稍后解密。我正在使用 Java 16,而我的 JRE 是 JavaSE-12。

class zip {
    public static void main(String[] args) throws IOException, InvalidKeyException, NoSuchPaddingException,
            NoSuchAlgorithmException, InvalidAlgorithmParameterException, BadPaddingException,
            IllegalBlockSizeException, InvalidKeySpecException {
        FileInputStream fis = new FileInputStream("texty.txt");
        FileOutputStream fos = new FileOutputStream("texty(comp)");
        DeflaterOutputStream dos = new DeflaterOutputStream(fos);

        int data;
        while ((data = fis.read()) != -1) {
            dos.write(data);
        }

        fis.close();
        dos.close();

        SecureRandom random = new SecureRandom();
        byte[] salt = new byte[16];
        random.nextBytes(salt);
        SecretKey key = getKeyFromPassword("Password", salt.toString());
        String algorithm = "AES/CBC/PKCS5Padding";
        byte[] iv = new byte[16];
        new SecureRandom().nextBytes(iv);
        IvParameterSpec Iv = new IvParameterSpec(iv);
        encryptFile(algorithm, key, Iv, new File("texty(comp)"), new File("texty(compNenc)"));
        FileOutputStream fs = new FileOutputStream(new File("intravenus"));
        BufferedOutputStream bos = new BufferedOutputStream(fs);
        bos.write(iv);
        bos.close();
        FileOutputStream fs2 = new FileOutputStream(new File("pepper"));
        BufferedOutputStream bos2 = new BufferedOutputStream(fs2);
        bos2.write(salt);
        bos2.close();
    }

    public static void encryptFile(String algorithm, SecretKey key, IvParameterSpec iv, File inputFile, File outputFile)
            throws IOException, NoSuchPaddingException, NoSuchAlgorithmException, InvalidAlgorithmParameterException,
            InvalidKeyException, BadPaddingException, IllegalBlockSizeException {

        Cipher cipher = Cipher.getInstance(algorithm);
        cipher.init(Cipher.ENCRYPT_MODE, key, iv);
        FileInputStream inputStream = new FileInputStream(inputFile);
        FileOutputStream outputStream = new FileOutputStream(outputFile);
        byte[] buffer = new byte[64];
        int bytesRead;
        while ((bytesRead = inputStream.read(buffer)) != -1) {
            byte[] output = cipher.update(buffer, 0, bytesRead);
            if (output != null) {
                outputStream.write(output);
            }
        }
        byte[] outputBytes = cipher.doFinal();
        if (outputBytes != null) {
            outputStream.write(outputBytes);
        }
        inputStream.close();
        outputStream.close();
    }

    public static SecretKey getKeyFromPassword(String password, String salt)
            throws NoSuchAlgorithmException, InvalidKeySpecException {

        SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256");
        KeySpec spec = new PBEKeySpec(password.toCharArray(), salt.getBytes(), 65536, 256);
        SecretKey secret = new SecretKeySpec(factory.generateSecret(spec).getEncoded(), "AES");
        return secret;
    }

}

更新:感谢@that other guy 帮助我解决最初的错误,但现在我有一个新的错误,我还不够先进,无法理解。当我尝试下载为 salt 和 IV 存储的字节并尝试解密文件时,我收到以下错误消息:

Exception in thread "main" javax.crypto.BadPaddingException: Given final block not properly padded. Such issues can arise if a bad key is used during decryption.
at java.base/com.sun.crypto.provider.CipherCore.unpad(CipherCore.java:975)
at java.base/com.sun.crypto.provider.CipherCore.fillOutputBuffer(CipherCore.java:1056)
at java.base/com.sun.crypto.provider.CipherCore.doFinal(CipherCore.java:853)
at java.base/com.sun.crypto.provider.AESCipher.engineDoFinal(AESCipher.java:446)
at java.base/javax.crypto.Cipher.doFinal(Cipher.java:2091)
at MyJavaProject.unzip.decryptFile(unzip.java:99)
at MyJavaProject.unzip.main(unzip.java:52)

下面列出了我的解密文件代码。如果有人可以提供帮助,我将不胜感激。

class unzip {
    public static void main(String[] args)
            throws IOException, NoSuchAlgorithmException, InvalidKeySpecException, InvalidKeyException,
            NoSuchPaddingException, InvalidAlgorithmParameterException, BadPaddingException, IllegalBlockSizeException {

        byte[] fileData = new byte[16];
        DataInputStream dis = null;

        dis = new DataInputStream(new FileInputStream(new File("intravenus")));
        dis.readFully(fileData);
        if (dis != null) {
            dis.close();
        }
        byte[] iv = fileData;
        IvParameterSpec Iv = new IvParameterSpec(iv);
        byte[] fileData2 = new byte[16];
        DataInputStream dis2 = null;

        dis2 = new DataInputStream(new FileInputStream(new File("pepper")));
        dis2.readFully(fileData2);
        if (dis2 != null) {
            dis2.close();
        }
        byte[] salt = fileData2;
        SecretKey key = getKeyFromPassword("Password", salt.toString());
        String algorithm = "AES/CBC/PKCS5Padding";

        decryptFile(algorithm, key, Iv, new File("texty(compNenc)"), new File("texty(compNdec)"));

        // assign Input File : file2 to FileInputStream for reading data
        FileInputStream fis = new FileInputStream("texty(compNdec)");

        // assign output file: file3 to FileOutputStream for reading the data
        FileOutputStream fos = new FileOutputStream("texty(decompNdec)");

        // assign inflaterInputStream to FileInputStream for uncompressing the data
        InflaterInputStream iis = new InflaterInputStream(fis);

        // read data from inflaterInputStream and write it into FileOutputStream
        int data;
        while ((data = iis.read()) != -1) {
            fos.write(data);
        }

        // close the files
        fos.close();
        iis.close();

    }

    public static SecretKey getKeyFromPassword(String password, String salt)
            throws NoSuchAlgorithmException, InvalidKeySpecException {

        SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256");
        KeySpec spec = new PBEKeySpec(password.toCharArray(), salt.getBytes(), 65536, 256);
        SecretKey secret = new SecretKeySpec(factory.generateSecret(spec).getEncoded(), "AES");
        return secret;
    }

    public static void decryptFile(String algorithm, SecretKey key, IvParameterSpec iv, File encryptedFile,
            File decryptedFile) throws IOException, NoSuchPaddingException, NoSuchAlgorithmException,
            InvalidAlgorithmParameterException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException {
        Cipher cipher = Cipher.getInstance(algorithm);
        cipher.init(Cipher.DECRYPT_MODE, key, iv);
        FileInputStream inputStream = new FileInputStream(encryptedFile);
        FileOutputStream outputStream = new FileOutputStream(decryptedFile);
        byte[] buffer = new byte[64];
        int bytesRead;
        while ((bytesRead = inputStream.read(buffer)) != -1) {
            byte[] output = cipher.update(buffer, 0, bytesRead);
            if (output != null) {
                outputStream.write(output);
            }
        }
        byte[] output = cipher.doFinal();
        if (output != null) {
            outputStream.write(output);
        }
        inputStream.close();
        outputStream.close();
    }

}
4

0 回答 0