2012-04-04 8 views
4

私はJavaでアプリケーションを作成しています。ユーザーが選択したパスワードを使用してファイル(またはフォルダ - 私はディレクトリを圧縮します)を暗号化できるようにします。私は、ファイルが生成される前に、ユーザーが正しいパスワードを入力したことを確認できるようにしたいプログラムよりユーザーフレンドリーを作るために、しかしPBE:復号化を試みる前にパスワードを確認する

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

:私は現在、以下の方法(複数可)を持っています。私は「ドアのマットの下に鍵を置いておく」、あるいは完全にセキュリティを元に戻すことはしません - ユーザーが間違ったパスワードを入力すると間違ったファイルが生成されないようにしたい...

アイデア大変感謝します。それ以上の詳細が必要な場合は、お気軽にお問い合わせください。

ありがとうございます。

+0

このようなものを実装する場合は、ユーザーが選択したファイルを圧縮しますが、パスワードの確認に使用される非常に小さいファイル(1バイト)を追加してファイルの内容を確認します。 –

答えて

2

PBEWithMD5AndDESではなくPBKDF2WithHmacSHA1を使用してください。後で2つの異なる古いプリミティブ。前者は現在の標準です。

は、次の2つのオプション

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

    明らかに、これは迅速に機能します。それは、攻撃者が無意識に試みることを意味するので、パスワードが推測されるパスワードを速く破棄することを意味するため、わずかに安全です。ファイル全体を見る必要はなく、その値をチェックするだけです。これは本当に大きな問題ではありません。鍵の導出関数は十分に難しく、それらを実行する必要があるからです。

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

+0

私はあなたがしなければならないことを知っていますが、私は「安全性が低い」という意味で「安全性が低い」と想定しています!また、これらのアイデアの上に展開すると、次のリンクでこのメソッドを使用して、ハッシュされたバージョンのパスワードをファイルの先頭に格納して確認し、残りのファイルの復号化を続けることができると思いますか?パスワードは正しいですか?もしそうなら、どれくらい安全でしょうか? http://www.rgagnon.com/javadetails/java-0400.html途中で、特にプリミティブ/スタンダードを使っていただきありがとうございます! – Andy

+0

また、私はPBKDF2WithHmacSHA1を実装し、PBEWithMD5AndDESと同じ暗号を作成しようとしましたが、そのたびに 'InvalidKeySpecException:Salt not found'を受け取ります。誰も知っている理由は?私はJava/JDKの最新バージョンを使用しています。 – Andy

+0

ええ、私は安全性が低いという意味です。パスワードハッシュを持つファイルが暗号化されている場合は、必ず暗号化されます。実際には、ファイルが安全なので、その時点でパスワードを保存するだけで済みます。 認証されたブロック暗号モードの操作(すべてのJavaプラットフォームではサポートされていません)を取得できるのであれば、本当に下の@ ericksonの投稿が参考になるでしょう 私はPBKDF2がPBEの代替品ではないと思います。それは私が考える別のパラメターが必要です。私はこれが実際の例であると信じています。http://stackoverflow.com/a/992413/980922 – imichaelmiers

3

暗号化されたパスワードをファイルに保存できます。ユーザーがパスワードを入力すると、そのパスワードが暗号化され、同じ暗号化されたパスワードがファイル内にあるかどうかがチェックされます。そうでない場合は、ファイルを読み込まないでください。

+0

あなたの答えをありがとうございますが、私はあなたが何を意味しているのかよく分かりません。パスワードを暗号化されたファイルの横にプレーンテキストとして保存するか、固定パスワード/アルゴリズムを使用して暗号化されたファイルにパスワードを保存する必要がありますか? ... – Andy

+0

ユーザーがファイルにパスワードを入力すると、暗号化されてファイルに保存されます(同じ方法で暗号化されます)。ユーザーがファイルを読み込むと、パスワードの入力を求められ、暗号化され、ファイルの暗号化されたパスワードと比較されます。パスワードはファイルに保存されますが、暗号化されます。私はそれがパスワードのようなものがUNIXに保存されていると思う。 –

+0

もう一度おねがいしますが、私はこの方法を使い終わってしまいましたが、今ではパスワードをファイルの先頭に保存しています(受け入れられた回答を読むと分かります)。 – Andy

1

私はAEADモード(CCMまたはEAXなど)を使用します。これにより、ファイルが復号化されるときにファイルの各ブロックの整合性がチェックされ、キーが正しくないか、ファイルが改ざんされた場合には失敗します。これらのモードのBouncy Castleプロバイダsupports both

+0

私の返答が足りないため、あなたの答えと誠実なご謝謝をありがとうございます。私はAEADモードを実装していましたが、正直言って私がやっていることにはちょっと複雑で、受け入れた答えは自分の状況に最も適しています... +1 – Andy

関連する問題