3

私は基本的に、Java/JSP 駆動の Web サイトで次のことをしようとしています。

  • ユーザーがパスワードを入力
  • パスワードは、サーバーに保存されているテキスト ファイルと多数のバイナリ ファイルを含む、強力に暗号化されたアーカイブ ファイル (zip など) を作成するために使用されます。基本的には、ユーザーのファイルと設定のバックアップです。
  • 後で、ユーザーがファイルをアップロードして元のパスワードを提供すると、サイトはアーカイブを復号化して解凍し、抽出されたバイナリ ファイルをサーバー上の適切なフォルダーに保存してから、サイトがユーザーのパスワードを復元できるようにテキスト ファイルを読み取ります。バイナリ ファイルに関する古い設定とメタデータ。

アーカイブを構築/暗号化してから、その内容を抽出する方法を理解しようとしています。非常に安全であることを除けば、アーカイブ形式についてはあまり気にしません。

私の問題に対する理想的な解決策は、実装が非常に簡単で、無料で制限のないライセンス (apache、berkeley、lgpl など) を備えた実証済みのライブラリのみが必要です。

TrueZIP および WinZipAES ライブラリを認識しています。前者はやり過ぎのようで、後者がどれほど安定しているかはわかりません...うまく機能する他のソリューションはありますか?

4

4 に答える 4

6

java.util.zipパッケージを使用して zip ファイルを作成する方法を知っている場合は、PBE暗号を作成し、それを CipherOutputStream または CipherInputStream に渡すことができます (読み取りまたは書き込みによって異なります)。

次の手順で開始できます。

public class ZipTest {

    public static void main(String [] args) throws Exception {
        String password = "password";
        write(password);
        read(password);
    }

    private static void write(String password) throws Exception {
        OutputStream target = new FileOutputStream("out.zip");
        target = new CipherOutputStream(target, createCipher(Cipher.ENCRYPT_MODE, password));
        ZipOutputStream output = new ZipOutputStream(target);

        ZipEntry e = new ZipEntry("filename");
        output.putNextEntry(e);
        output.write("helloWorld".getBytes());
        output.closeEntry();

        e = new ZipEntry("filename1");
        output.putNextEntry(e);
        output.write("helloWorld1".getBytes());
        output.closeEntry();

        output.finish();
        output.flush();
    }

    private static Cipher createCipher(int mode, String password) throws Exception {
        String alg = "PBEWithSHA1AndDESede"; //BouncyCastle has better algorithms
        PBEKeySpec keySpec = new PBEKeySpec(password.toCharArray());
        SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(alg);
        SecretKey secretKey = keyFactory.generateSecret(keySpec);

        Cipher cipher = Cipher.getInstance("PBEWithSHA1AndDESede");
        cipher.init(mode, secretKey, new PBEParameterSpec("saltsalt".getBytes(), 2000));

        return cipher;
    }

    private static void read(String password) throws Exception {
        InputStream target = new FileInputStream("out.zip");
        target = new CipherInputStream(target, createCipher(Cipher.DECRYPT_MODE, password));
        ZipInputStream input = new ZipInputStream(target);
        ZipEntry entry = input.getNextEntry();
        while (entry != null) {
            System.out.println("Entry: "+entry.getName());
            System.out.println("Contents: "+toString(input));
            input.closeEntry();
            entry = input.getNextEntry();
        }
    }

    private static String toString(InputStream input) throws Exception {
        byte [] data = new byte[1024];
        StringBuilder result = new StringBuilder();

        int bytesRead = input.read(data);
        while (bytesRead != -1) {
            result.append(new String(data, 0, bytesRead));
            bytesRead = input.read(data);
        }

        return result.toString();
    } 
}
于 2009-11-13T16:29:01.473 に答える
4

答えはすでに与えられているので (Kevin が指摘したように暗号を使用してください)、トピックに欠けていると思われる重要な事項について提案するだけですstart:HTTPS代わりにHTTP. そうしないと、ネットワーク スニファを使用する人が、ユーザーが指定したパスワードをパケットから取得できてしまいます。その方法は、問題のアプリケーションサーバーによって異なります。そのドキュメントを参照することをお勧めします。たとえば Apache Tomcat の場合は、Tomcat SSL HOW-TOですべてを見つけることができます。

お役に立てれば。

于 2009-11-13T16:38:17.150 に答える
0

あなたのクエリに固有のものではないかもしれませんが、truecryptが役立つのではないかと思います. Web サーバーは、zip ファイルがコピーされる暗号化されたコンテナを作成できます。その後、暗号化されたコンテナーをダウンロードできます。少し厄介な可能性がありますが、暗号化は強力である必要があり、ダウンロードしたイメージはさまざまなオペレーティング システムにマウントできます。

于 2009-11-13T16:57:03.133 に答える
0

ここには、問題を解決する方法に関するいくつかの提案が確かにありますが、応答には非常に大きなBUTがありません. 「強力な暗号化」の合理的な定義について、「パスワードベース」と「強力な暗号化」の両方を満たすことはできません。

于 2009-11-13T17:10:42.847 に答える