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

PBEWithMD5AndDES ではなく、PBKDF2WithHmacSHA1 を使用します。後のユーザーは、2 つの異なる古いプリミティブを使用します。前者が現在の標準です。

あなたには2つの選択肢があります

  1. 高速だが安全性が低い: 暗号化されたファイルの先頭に短い既知の値を配置するか、まったく別の短いファイルを同じパスワードで暗号化します。このファイルを復号化するときは、既知の値を確認してください。

    明らかに、これは迅速に機能します。パスワードをブルート フォースしようとする攻撃者が、推測したパスワードをより速く破棄できることを意味するため、安全性がわずかに低くなります。ファイル全体を調べる代わりに、その値を確認するだけで済みます。キー派生関数は十分に難しく、実行する必要があるため、これは実際には大きな問題ではありません。

  2. 暗号化されたファイルのハッシュも保存し、復号化時にハッシュを検証します。攻撃者がファイル全体を復号化して読み取る必要があるという点でより安全ですが、同じように低速です。

于 2012-04-05T04:07:13.957 に答える
1

CCMやEAXなどのAEADモードを使用します。これにより、ファイルが復号化されるときにファイルのすべてのブロックの整合性がチェックされ、キーが正しくないか、ファイルが改ざんされている場合は失敗します。バウンシーキャッスルプロバイダーは、これらのモードの両方をサポートしています。

于 2012-04-05T04:42:08.247 に答える