8

私は暗号化を取り上げようとしており、この演習を試みていました

ワンタイム パッドを生成するプログラム (できれば Java) を作成します。ワンタイム パッドは、すべてのランダム データの比較的大きなファイル (1 MB など) です。プログラムは、生成されたワンタイムパッドに基づいてファイルを暗号化/復号化することもできます。

ヒント: 次のテスト ベクトルを使用して、プログラムが正しく暗号化されているかどうかを確認してください。

平文 (ASCII): すべての雲には希望の光があり
ます OTP (HEX): 6dc72fc595e35dcd38c05dca2a0d2dbd8e2df20b129b2cfa29ad17972922a2
暗号文 (HEX): 28b14ab7ecc33ea157b539ea426c5eef9def0d81627cc89eed495

乱数ジェネレーターを HEX 形式に変換する必要があるため、乱数ジェネレーターを使用してワンタイム パッドを生成しようとしました。そして、私は混乱しているか、正しい方法で取り組んでいないと確信しています

public static void oneTimePad()
{
    Random ran = new Random();
    String s = "0123456789ABCDEF";
    for(int i = 0; i < 100; i++)
    {   
        System.out.print(s.charAt(ran.nextInt(s.length())));
    }
}

上記は私のワンタイムパッドであり、ワンタイムパッドを使用して暗号化を実装し、それを復号化する方法を考えていました。

4

6 に答える 6

10

ここに完全に機能する例があります:

    // convert secret text to byte array
    final byte[] secret = "secret".getBytes()

    final byte[] encoded = new byte[secret.length];
    final byte[] decoded = new byte[secret.length];

    // Generate random key (has to be exchanged)
    final byte[] key = new byte[secret.length];
    new SecureRandom().nextBytes(key);

    // Encrypt
    for (int i = 0; i < secret.length; i++) {
        encoded[i] = (byte) (secret[i] ^ key[i]);
    }

    // Decrypt
    for (int i = 0; i < encoded.length; i++) {
        decoded[i] = (byte) (encoded[i] ^ key[i]);
    }

    assertTrue(Arrays.equals(secret, decoded));
于 2013-05-24T09:31:41.010 に答える
3

ワンタイムパッドには、16 進数ではなくバイト配列が必要です。16 進数は、データの表示にのみ必要です (ビットの読み取りに問題が発生する傾向があります)。Apache Commons ライブラリ (コーデック パッケージ) を使用して、バイト配列から 16 進数を作成したり、テスト ベクトルを 16 進数からバイトにデコードしたい場合は元に戻すことができます。

ではなく、安全な乱数ジェネレーターを使用する必要がありますRandomnew SecureRandom()代わりに使用してください。ランダム データを生成するには、まずバイト配列を作成し、次にnextBytes()乱数ジェネレーターを呼び出します。整数を生成する必要はありません。

于 2012-11-02T01:01:00.067 に答える
2

まず、標準の RFC である HOTP と呼ばれる OTP アルゴリズムが指定されています。他のほとんどすべての OTP は適切であり、それらのアルゴリズムはわかりません。

https://www.rfc-editor.org/rfc/rfc4226

そこには、それがどのように行われたかを学ぶために使用できるJavaコードがいくつかあります。次に、暗号化を行う場合はランダムを使用しないでください。乱数は疑似乱数に適していますが、乱数データの優れたソースが本当に必要な場合は、SecureRandom を採用する必要があります。これは、cryto アルゴリズムに適した乱数のはるかに優れたソースです。

物事をHexに変換するには、簡単に使用できます

http://docs.oracle.com/javase/1.5.0/docs/api/java/math/BigInteger.html#toString(int)

または、さまざまな Long.toString(value,radix)、Integer.toString(value,radix)、または Byte.toString(value,radix) のいずれかです。

byte[] bytes = ...;
for( int i = 0; i < bytes.length; i++ ) {
    System.out.println( Integer.toString( bytes[i], 16 );
}
于 2012-11-02T01:03:43.140 に答える