在Android中加密和解密zip文件?

我正在使用此代码: http : //examples.javacodegeeks.com/core-java/crypto/encrypt-decrypt-file-stream-with-des用于加密我在Android应用程序中使用的zip文件。它工作得非常好当我使用java代码尝试使用zip文件时,但是当我在Android应用程序中尝试相同的方法时 – 它解密文件但我得到的文件已损坏且无法打开它。

日志:

04-19 10:58:25.711: W/System.err(6752): net.lingala.zip4j.exception.ZipException: zip headers not found. probably not a zip file 04-19 10:58:25.721: W/System.err(6752): at net.lingala.zip4j.core.HeaderReader.readEndOfCentralDirectoryRecord(HeaderReader.java:122) 

当我尝试使用winzip在Windows上打开相同的文件时,它会显示:

  Does not appear to be a valid archive file. 

更新::

 public class EncryptDecryptFileStreamWithDES { private static Cipher ecipher; private static Cipher dcipher; // 8-byte initialization vector private static byte[] iv = { (byte)0xB2, (byte)0x12, (byte)0xD5, (byte)0xB2, (byte)0x44, (byte)0x21, (byte)0xC3, (byte)0xC3 }; public static void call() { try { SecretKey key = KeyGenerator.getInstance("DES").generateKey(); AlgorithmParameterSpec paramSpec = new IvParameterSpec(iv); ecipher = Cipher.getInstance("DES/CBC/PKCS5Padding"); dcipher = Cipher.getInstance("DES/CBC/PKCS5Padding"); ecipher.init(Cipher.ENCRYPT_MODE, key, paramSpec); dcipher.init(Cipher.DECRYPT_MODE, key, paramSpec); // encrypt(new FileInputStream("C:\\Users\\Admin\\Desktop\\zipped\\4.zip"), new FileOutputStream("C:\\Users\\Admin\\Desktop\\zipped\\4.dat")); // decrypt(new FileInputStream("C:\\Users\\Admin\\Desktop\\zipped\\4.dat"), new FileOutputStream("C:\\Users\\Admin\\Desktop\\zipped\\4new.zip")); //} //catch (FileNotFoundException e) { //System.out.println("File Not Found:" + e.getMessage()); //return; } catch (InvalidAlgorithmParameterException e) { System.out.println("Invalid Alogorithm Parameter:" + e.getMessage()); return; } catch (NoSuchAlgorithmException e) { System.out.println("No Such Algorithm:" + e.getMessage()); return; } catch (NoSuchPaddingException e) { System.out.println("No Such Padding:" + e.getMessage()); return; } catch (InvalidKeyException e) { System.out.println("Invalid Key:" + e.getMessage()); return; } } public static void encrypt(InputStream is, OutputStream os) { try { call(); byte[] buf = new byte[1024]; // bytes at this stream are first encoded os = new CipherOutputStream(os, ecipher); // read in the clear text and write to out to encrypt int numRead = 0; while ((numRead = is.read(buf)) >= 0) { os.write(buf, 0, numRead); } // close all streams os.close(); } catch (IOException e) { System.out.println("I/O Error:" + e.getMessage()); } } public static void decrypt(InputStream is, OutputStream os) { try { call(); byte[] buf = new byte[1024]; // bytes read from stream will be decrypted CipherInputStream cis = new CipherInputStream(is, dcipher); // read in the decrypted bytes and write the clear text to out int numRead = 0; while ((numRead = cis.read(buf)) > 0) { os.write(buf, 0, numRead); } // close all streams cis.close(); is.close(); os.close(); } catch (IOException e) { System.out.println("I/O Error:" + e.getMessage()); } } } 

这是我正在使用的类:

问题是您使用不同的密钥来加密和解密文件:

1)您从EncryptDecryptFileStreamWithDES之外的某个地方调用encrypt(..) ,然后调用您的call()方法,该方法初始化新密钥:

 SecretKey key = KeyGenerator.getInstance("DES").generateKey(); 

2)然后你调用decrypt(..) ,再次调用你的call()方法,你得到新的SecretKey

在您使用的示例中没有这样的问题,这些方法调用的顺序相反。 要扩展此示例,您需要在调用encrypt(..)decrypt(..)之间按住键,然后使用存储的密钥初始化SecretKeySpec

 byte[] keyBytes = KeyGenerator.getInstance("AES").getEncoded(); ... SecretKeySpec skeySpec = new SecretKeySpec(keyBytes, "AES"); Cipher cipher = Cipher.getInstance("AES"); cipher.init(Cipher.DECRYPT_MODE, skeySpec); 

这是一个更现实的例子。

PS正如提到的那样,使用DES算法不是最好的主意,而是使用AES