“如何调试”;给定未正确填充的最后一块“;在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);