“如何调试”;给定未正确填充的最后一块“;在Java中使用MD5和DES?

“如何调试”;给定未正确填充的最后一块“;在Java中使用MD5和DES?,java,encryption,cryptography,md5,des,Java,Encryption,Cryptography,Md5,Des,我的计算机上有使用以下代码加密的文件: //Arbitrarily selected 8-byte salt sequence: private static final byte[] salt = { (byte) 0x43, (byte) 0x76, (byte) 0x95, (byte) 0xc7, (byte) 0x5b, (byte) 0xd7, (byte) 0x45, (byte) 0x17 }; public static Cipher makeCipher(

我的计算机上有使用以下代码加密的文件:

//Arbitrarily selected 8-byte salt sequence:
private static final byte[] salt = {
    (byte) 0x43, (byte) 0x76, (byte) 0x95, (byte) 0xc7,
    (byte) 0x5b, (byte) 0xd7, (byte) 0x45, (byte) 0x17 
};

public static Cipher makeCipher(String pass, Boolean decryptMode) throws GeneralSecurityException{

    //Use a KeyFactory to derive the corresponding key from the passphrase:
    PBEKeySpec keySpec = new PBEKeySpec(pass.toCharArray());
    SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("PBEWithMD5AndDES");//PBKDF2WithHmacSHA256
    SecretKey key = keyFactory.generateSecret(keySpec);

    //Create parameters from the salt and an arbitrary number of iterations:
    PBEParameterSpec pbeParamSpec = new PBEParameterSpec(salt, 42);

    //Set up the cipher:
    Cipher cipher = Cipher.getInstance("PBEWithMD5AndDES");

    //Set the cipher mode to decryption or encryption:
    if(decryptMode){
        cipher.init(Cipher.ENCRYPT_MODE, key, pbeParamSpec);
    } else {
        cipher.init(Cipher.DECRYPT_MODE, key, pbeParamSpec);
    }

    return cipher;
}


/**Encrypts one file to a second file using a key derived from a passphrase:**/
public static void encryptFile(String fileName, String pass){
    try{
        byte[] decData;
        byte[] encData;
        File inFile = new File(fileName);
        //Generate the cipher using pass:
        Cipher cipher = Main.makeCipher(pass, true);

        //Read in the file:
        FileInputStream inStream = new FileInputStream(inFile);

        int blockSize = 8;
        //Figure out how many bytes are padded
        int paddedCount = blockSize - ((int)inFile.length()  % blockSize );

        //Figure out full size including padding
        int padded = (int)inFile.length() + paddedCount;

        decData = new byte[padded];


        inStream.read(decData);

        inStream.close();

        //Write out padding bytes as per PKCS5 algorithm
        for( int i = (int)inFile.length(); i < padded; ++i ) {
            decData[i] = (byte)paddedCount;
        }

        //Encrypt the file data:
        encData = cipher.doFinal(decData);

        writeToFile(fileName, encData);

    } catch(Exception e){
        e.printStackTrace();
    }
}

private static void writeToFile(String path, byte[] data) {
    try {
        File file = new File(path);

        //Write the encrypted data to a new file:
        FileOutputStream outStream = new FileOutputStream(file);
        outStream.write(data);
        outStream.close();
    } catch(Exception e){
        e.printStackTrace();
    }
}
但在尝试解密文件时,会引发以下错误:

Exception in thread "main" javax.crypto.BadPaddingException: Given final block not properly padded
at com.sun.crypto.provider.CipherCore.doFinal(CipherCore.java:966)
at com.sun.crypto.provider.CipherCore.doFinal(CipherCore.java:824)
at com.sun.crypto.provider.PBES1Core.doFinal(PBES1Core.java:416)
at com.sun.crypto.provider.PBEWithMD5AndDESCipher.engineDoFinal(PBEWithMD5AndDESCipher.java:316)
at javax.crypto.Cipher.doFinal(Cipher.java:2165)
at Main.decryptFile(Main.java:145)
at Main.main(Main.java:22)
这是哪一行:

decData = cipher.doFinal(encData);
这只是许多文件中的一个。我所有的编程项目、网站、工作、实习相关文件都是加密的

如果有人能帮我恢复对文件的访问权限,我将不胜感激。文件被加密的原因是因为我的用户文件夹的一些错误权限设置,在测试后我没有更改回去。现在已经修好了

是否可能我没有正确加密数据,因此无法解密

我上传了一个加密的word文档,这样您就可以了解问题所在。可以在这里找到:


此文档包含3个HTML/CSS相关检查列表。

此异常消息表示密钥错误。

首先使用DES对加密数据进行解密

如果密钥错误,则生成的数据将是随机的。有一个概率
1/256
它将以
0x01
结束,这是一个正确的PKCS填充,一个概率
1/(256*256)
它将以
0x02 0x02
结束,这也是一个正确的填充,概率
1/(256*256*256)
它将以
0x03 0x03 0x03
结束,这也是一个正确的填充,在这些极不可能的情况下不会引发异常,但解密的数据当然是不正确的



上面OP的代码中有一个重要的错误:
encryptFile
方法执行输入填充,尽管它不必执行:
doFinal(…)
也添加填充。这就是为什么添加两次填充,解密后的结果数据中保留一个填充。

总之,您是否意外加密了这些文件?如果您正在尝试解密,我首先建议检查您的备份-您有什么可以帮助您的吗?如果没有,那么至少您有一个密码短语和代码可以尝试,所以很可能不会丢失所有内容。但是,如果您需要坚持解密,请先进行备份-您可能会做一些使事情变得更糟的事情,因此请采取预防措施。您好,是的,我在错误的文件夹上运行了一个项目,导致了此问题。很遗憾我没有备份。我同意,我现在就来。非常感谢您的回复!请看,我已经回答了这些问题。它们不能帮助我更接近导致抛出错误的原因。谢谢你指出你有一个加密的文本文件你知道第一个字符吗?一些带有头文件的XML,例如。。。
decData = cipher.doFinal(encData);