您同时使用
Cipher.ENCRYPT_MODE解密和加密。您应该使用它
Cipher.DECRYPT_MODE来解密文件。
该问题已得到解决,但您的布尔值是错误的。加密时为true,解密时为false。我强烈建议您不要将其
false/true用作函数参数,而应始终使用
Cipher.ENCRYPT…
然后,您将加密为.encrypted文件,但尝试解密原始的纯文本文件。
然后,您不将填充应用于加密。我很惊讶这实际上是必须手动完成的,但是这里会解释填充。填充方案PKCS5似乎在这里隐式使用。
这是完整的工作代码,将加密文件写入
test.txt.encrypted,将解密文件写入
test.txt.decrypted.txt。注释中说明了在加密中添加填充并在解密中删除填充。
import java.io.File;import java.io.FileInputStream;import java.io.FileOutputStream;import java.io.FileWriter;import java.io.IOException;import java.security.GeneralSecurityException;import java.util.Arrays;import javax.crypto.Cipher;import javax.crypto.SecretKey;import javax.crypto.SecretKeyFactory;import javax.crypto.spec.PBEKeySpec;import javax.crypto.spec.PBEParameterSpec;public class FileEncryptor { public static void main( String[] args ) { try { encryptFile( "C:\test.txt", "password" ); decryptFile( "C:\test.txt", "password" ); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (GeneralSecurityException e) { // TODO Auto-generated catch block e.printStackTrace(); } } //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 }; private 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"); SecretKey key = keyFactory.generateSecret(keySpec); //Create parameters from the salt and an arbitrary number of iterations: PBEParameterSpec pbeParamSpec = new PBEParameterSpec(salt, 42); FileEncryptor.keyToFile(key); //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; } public static void encryptFile(String fileName, String pass) throws IOException, GeneralSecurityException{ byte[] decData; byte[] encData; File inFile = new File(fileName); //Generate the cipher using pass: Cipher cipher = FileEncryptor.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); //Write the encrypted data to a new file: FileOutputStream outStream = new FileOutputStream(new File(fileName + ".encrypted")); outStream.write(encData); outStream.close(); } public static void decryptFile(String fileName, String pass) throws GeneralSecurityException, IOException{ byte[] encData; byte[] decData; File inFile = new File(fileName+ ".encrypted"); //Generate the cipher using pass: Cipher cipher = FileEncryptor.makeCipher(pass, false); //Read in the file: FileInputStream inStream = new FileInputStream(inFile ); encData = new byte[(int)inFile.length()]; inStream.read(encData); inStream.close(); //Decrypt the file data: decData = cipher.doFinal(encData); //Figure out how much padding to remove int padCount = (int)decData[decData.length - 1]; //Naive check, will fail if plaintext file actually contained //this at the end //For robust check, check that padCount bytes at the end have same value if( padCount >= 1 && padCount <= 8 ) { decData = Arrays.copyOfRange( decData , 0, decData.length - padCount); } //Write the decrypted data to a new file: FileOutputStream target = new FileOutputStream(new File(fileName + ".decrypted.txt")); target.write(decData); target.close(); } private static void keyToFile(SecretKey key){ try { File keyFile = new File("C:\keyfile.txt"); FileWriter keyStream = new FileWriter(keyFile); String enpredKey = "n" + "Enpred version of key: " + key.getEnpred().toString(); keyStream.write(key.toString()); keyStream.write(enpredKey); keyStream.close(); } catch (IOException e) { System.err.println("Failure writing key to file"); e.printStackTrace(); } }}


