【问题标题】:Encrypting and decrypting a zip file in Android?在 Android 中加密和解密 zip 文件?
【发布时间】:2012-04-19 15:40:55
【问题描述】:

我正在使用此代码: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) 

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

   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());
    }

}

}

这是我正在使用的类:

【问题讨论】:

  • 如果我们看不到您的代码,我们怎么知道您做错了什么?
  • 比较解密后的文件大小和原始文件的大小。并显示您的实际代码。顺便说一句,你可能不应该使用 DES,现在很容易暴力破解。
  • 大小与原压缩包相同

标签: java android zip encryption


【解决方案1】:

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

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);

Here 是一个更真实的例子。

附:如前所述,使用DES 算法不是最好的主意,请改用AES

【讨论】:

猜你喜欢
  • 1970-01-01
  • 2011-05-15
  • 1970-01-01
  • 2012-01-01
  • 2010-11-27
  • 1970-01-01
  • 1970-01-01
  • 2010-12-26
相关资源
最近更新 更多