4

我正在用 Java 制作应用程序,我希望允许用户使用他们选择的密码来加密文件(或文件夹 - 我会压缩目录)。我目前有以下方法:

static Cipher createCipher(int mode, String password) throws Exception {
            PBEKeySpec keySpec = new PBEKeySpec(password.toCharArray());
            SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("PBEWithMD5AndDES");
            SecretKey key = keyFactory.generateSecret(keySpec);
            MessageDigest md = MessageDigest.getInstance("MD5");
            md.update("input".getBytes());
            byte[] digest = md.digest();
            byte[] salt = new byte[8];
            for (int i = 0; i < 8; ++i)
              salt[i] = digest[i];
            PBEParameterSpec paramSpec = new PBEParameterSpec(salt, 20);
            Cipher cipher = Cipher.getInstance("PBEWithMD5AndDES");
            cipher.init(mode, key, paramSpec);
            return cipher;
    }

     static void applyCipher(String inFile, String outFile, Cipher cipher) throws Exception {
            String decryption = "";
            CipherInputStream in = new CipherInputStream(new FileInputStream(inFile), cipher);
            BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(outFile));
            int BUFFER_SIZE = 8;
            byte[] buffer = new byte[BUFFER_SIZE];
            int numRead = 0;
            do {
              numRead = in.read(buffer);
              System.out.println(buffer + ", 0, " + numRead);
              if (numRead > 0){
                out.write(buffer, 0, numRead);
                System.out.println(toHexString(buffer, 0, numRead));
              }
             } while (numRead == 8);
            in.close();
            out.flush();
            out.close();
          }
     private static char[] hex_table = {
            '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 
            'a', 'b', 'c', 'd', 'e', 'f'};

     public static String toHexString(byte[] data, int offset, int length)
     {
       StringBuffer s = new StringBuffer(length*2);
       int end = offset+length;

       for (int i = offset; i < end; i++)
       {
         int high_nibble = (data[i] & 0xf0) >>> 4;
         int low_nibble = (data[i] & 0x0f);
         s.append(hex_table[high_nibble]);
         s.append(hex_table[low_nibble]);
       }

       return s.toString();
     }

但是,为了使程序更加用户友好,我希望能够在生成文件之前检查用户是否输入了正确的密码。我不想“将钥匙留在门垫下”或完全取消安全性等-我只想防止在用户输入错误密码时生成错误的文件...

任何想法将不胜感激。如果您需要更多详细信息,请随时询问。

提前致谢

4

3 回答 3

3

您可以将加密的密码与文件一起保存。当用户输入密码时,您对其进行加密并检查文件中是否存在相同的加密密码。如果没有,则不加载文件。

于 2012-04-04T14:25:26.967 回答
2

使用 PBKDF2WithHmacSHA1 而不是 PBEWithMD5AndDES。后来用户使用了两种不同的过时原语。前者是现行标准。

你有两个选择

  1. 快速但不太安全:在加密文件的开头放置一个已知的短值,或者使用相同的密码加密一个完全不同的短文件。解密此文件时,请检查已知值。

    显然,这很快就奏效了。它的安全性稍差一些,因为这意味着试图暴力破解密码的攻击者可以更快地丢弃猜测的密码:他们不必查看整个文件,只需检查该值即可。这并不是一个真正的大问题,因为您的密钥派生函数应该足够难,而且他们仍然必须运行它

  2. 存储加密文件的哈希值,并在解密时验证哈希值。更安全的是,攻击者必须解密整个文件并通读它,但出于同样的原因,它很慢。

于 2012-04-05T04:07:13.957 回答
1

我会使用AEAD模式,例如 CCM 或 EAX。这将在解密文件时检查文件每个块的完整性,如果密钥不正确或文件已被篡改,则会失败。Bouncy Castle 提供程序支持这两种模式。

于 2012-04-05T04:42:08.247 回答