7

BigIntegers を使用して、Java で DES 暗号化を実装しています。

BigInteger.leftShift(int n) メソッドを実行して、Java BigIntegers でバイナリ キーを左シフトしています。N (Kn) のキーは、Kn-1 のシフトの結果に依存します。私が得ている問題は、各キーが生成された後に結果を出力していて、シフトが期待される出力ではないことです。キーは 2 つの Cn と Dn (それぞれ左と右) に分割されます。

私は具体的にこれを試みています。

シフトによっては末尾に○を付けるようです。これを修正する方法がわかりません。

結果:

c0: 11110101010100110011000011110

d0: 11110001111001100110101010100

c1: 111101010101001100110000111100

d1: 111100011110011001101010101000

c2: 11110101010100110011000011110000

d2: 11110001111001100110101010100000

c3: 1111010101010011001100001111000000

d3: 1111000111100110011010101010000000

c4: 111101010101001100110000111100000000

d4: 111100011110011001101010101000000000

c5: 11110101010100110011000011110000000000

d5: 11110001111001100110101010100000000000

c6: 1111010101010011001100001111000000000000

d6: 1111000111100110011010101010000000000000

c7: 111101010101001100110000111100000000000000

d7: 111100011110011001101010101000000000000000

c8: 1111010101010011001100001111000000000000000

d8: 1111000111100110011010101010000000000000000

c9: 111101010101001100110000111100000000000000000

d9: 111100011110011001101010101000000000000000000

c10: 1111010101010011001100001111000000000000000000

d10: 1111000111100110011010101010000000000000000000

c11: 111101010101001100110000111100000000000000000000

d11: 111100011110011001101010101000000000000000000000

c12: 11110101010100110011000011110000000000000000000000

d12: 11110001111001100110101010100000000000000000000000

c13: 1111010101010011001100001111000000000000000000000000

d13: 1111000111100110011010101010000000000000000000000000

c14: 111101010101001100110000111100000000000000000000000000

d14: 111100011110011001101010101000000000000000000000000000

c15: 1111010101010011001100001111000000000000000000000000000

d15: 111100011110011001101010101000000000000000000000000000

4

4 に答える 4

10

BigInteger は無限精度の整数を実装しているため、左にシフトすると左にゼロが追加され続けます。回転が必要です:

private static BigInteger rotateLeft(BigInteger bi) {
    BigInteger ret = bi.shiftLeft(1);
    if (ret.testBit(32)) {
        ret = ret.clearBit(32).setBit(0);
    }
    return ret;
}

これは 32 ビットの数値ではかなり非効率になるため、プリミティブを使用して DES の 28 ビットの半分をローテーションすることもできます。私は DES アルゴリズムに詳しくないので、BigInteger は別の目的で必要になると思います。

private static BigInteger rotateLeftPrimitive(BigInteger bi) {
    int value = bi.intValue();
    return BigInteger.valueOf(((value << 1) & 0xffffffe) | ((value >>> 27) & 1));
}
于 2010-04-28T05:35:22.600 に答える
4

巡回左シフトが必要なようです。BigInteger.shiftLeft周期的ではありません。と を使用する場合と同様にshiftLeft、 、shiftRightandおよびを組み合わせる必要があります。orint<<

static BigInteger allOnes(int L) {
    return BigInteger.ZERO
        .setBit(L)
        .subtract(BigInteger.ONE);
}

static BigInteger cyclicLeftShift(BigInteger n, int L, int k) {
    return n.shiftLeft(k)
        .or(n.shiftRight(L - k))
        .and(allOnes(L));
}

ここで、循環ウィンドウが である左に巡回シフトされたビットをcyclicLeftShift(n, L, k)返します。nkL

これがどのように機能するかは次のとおりです。

                               _________L__________
                              /                    \
n :                           [ABCDE][FG...........]
                              \__k__/\_____L-k_____/



n.shiftLeft(k) :       [ABCDE][FG...........][00000]
   .or
n.shiftRight(L - k) :                        [ABCDE]

   =                   [ABCDE][FG...........][ABCDE]

                               _________L__________
   .and                       /                    \
allOnes(L) :                  [111..............111]

   =                          [FG...........][ABCDE]

こちらもご覧ください


: が固定されている場合は、毎回計算する代わりにLキャッシュすることで、これを少し最適化できます。allOnes(L)

于 2010-04-28T05:31:48.660 に答える
1

より大きな問題に対処すると、1) DES は壊れており、レガシー システムでの作業以外に使用してはならない、2) Sun JCE は既に実装を提供している (BouncyCastle や他の暗号プロバイダーと同様)、3) 暗号アルゴリズムの実装はやりがいがあり、本番環境で使用するために十分にテストされた実装を本当に使用したい.

クラスの演習であれば、BigInteger の代わりに byte[] を使用します。もう少し手動で行う必要がありますが、ハードウェアに簡単に実装できるように設計されているため、DES の精神により近いものになっています。

于 2010-04-28T17:00:46.210 に答える
0

ビット文字列を使用して DES を実装するというあなたの考えは、教育ツールとして合理的だと思います。BigIntegers を直接使用してこれらのビット文字列を表すのではなく、プロジェクトに必要なビット文字列メソッドを正確に実装する BitString クラスを作成することをお勧めします。BitString クラス内では BigIntegers を使用できますが、配列要素ごとに 1 ビットの単純な int 配列、またはリンクされたリストの方が簡単であることがわかる場合があります。

于 2010-04-29T01:19:02.463 に答える