DES アルゴリズム (完全) を実装する方法。
これは清華BBSからの抜粋です。外国語なので専門家の指導を仰ぎます。
セミコロン(;)以降は私の訳、シャープ(#)以降は私の考えです。
バージョン1.2
1977年に米国政府が採用したデータ暗号化標準(DES)アルゴリズムは、順列によって56ビットの秘密キーの下で64ビットデータブロックを変換するブロック暗号です。これは
FIPS PUB 46 で正式に説明されています。DES アルゴリズムは、
政府内および民間部門の多くのアプリケーションで使用されています
これは、
初心者向けにわかりやすく設計されたチュートリアルです。
印刷された作品を追跡したり、C
ソースコードを調べたりすることなく、実装に必要なすべての情報を DES に送信できます。
Matthew Fischer
; 上記は紹介文なので読みません。 ;)
その方法を段階的に説明します:
1 鍵を処理します
;鍵を生成します
1.1 ユーザーから 64 ビット鍵を取得します (8 番目のビットごとに
パリティ ビットとみなされます。キーに正しいパリティを持たせるには、各バイトに
奇数の「1」ビットが含まれている必要があります。)
; ユーザーから 64 ビット キーを取得します。 (8 ビットの各グループ、各グループの 8 番目のビットがチェック ビットです。チェック
が正しい場合、各バイトの
は 1.2 であるはずです。 鍵スケジュールを計算します。
; 鍵テーブルを計算します
1.2.1 64 ビット鍵に対して次の置換を実行します (パリティ
ビットが破棄され、鍵が 56 ビットに減ります。置換された
ブロックのビット 1 は元の鍵のビット 57、ビット 2 はビット 49 などになります。ビット
56 は元のキーのビット 4 です。)
; 64 ビットのキーに対して次の置換を実行します (チェック ディジットを削除すると、キーの実際の長さは 56 ビットになります。置換後の最初の桁は、
;は元のキーの 57 桁目、2 桁目は元の 49 桁目、56 桁目は元のキーの 4 桁目です)
# この奇妙な順列の式を書ける人はいますか? # 分割されているようです。 2 つの部分に分けます
# for(j=57;j<64;j++)
# {
# for(i=j;i<0;i-=8)
# {
# if(k= "これは最初の 28、正しいかどうかわかりません ~ 10 2 59 51 43 35 27
19 11 3 60 52 44 36 7 62 54 46 38 30 22
最初の 28 ビットは C[0] と呼ばれ、最後の 28 ビットは C[0] と呼ばれます。 28 ビットは D[0] と呼ばれます。 ; 置換されたキーを 2 つの部分 C[0] と D[0] に分割し、それぞれ 28 ビットにします。
1.2.3 i = 1 から始めて 16 個のサブキーを計算します。
;i=1 から始めて 16 個のサブキーを計算します。
1.2.3.1 C[i-1] と
D[i-1] の両方で 1 つまたは 2 つの循環左シフトを実行して、それぞれ C[i] と D[i] を取得します。
反復ごとのシフト数は次のとおりです。以下の表に示す
; C[i-1] と D[i-1] に対してそれぞれ 1 ~ 2 ビットの左シフト演算を実行して、C[i] と D[i] を取得します。各回
; 変位の回数は次のとおりです:
# 合計 16 回
反復 # 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
左シフト 1 1 2 2 2 2 2 2 1 2 2 2 2 2 2 1
1.2.3.2 以下に示すように連結 C[i]D[i] を並べ替えると、次の表に示すように 48 ビット長の K[i] が生成されます。 、C[i]とD[i]を変更すると、48ビット長のk[i]が得られます。 (# 理解できません: (不# 少し間違えましたか?
並べ替え選択肢 2 (PC-2)
14 17 11 24 1 5
38 15 6 21 10
23 4 26 8
16
16 7 27 20 13 2
44 49 39 56 34 53 ] が計算されました
;16 ワードのデータ ブロックを計算するために
;64- を処理します。
2.1 64 ビット データ ブロックを取得します。ブロックが 64 ビットより短い場合は、
データ ブロックを取得します。 64 ビット未満の場合は、64 ビットを使用します。
# は 0 で埋めてください。
2.2 データ ブロックに対して次の置換を実行します。最初の部分は偶数です。計算は書かれていません
初期順位(IP)
57 41 33 25 17 9 1
2.4 i = 1 から開始して 16 個のサブキーをデータ ブロックに適用します。
;i=1 から開始して、16 個のサブキーを使用してデータ ブロックを暗号化します。
2.4.1 以下の
ビット選択関数に従って 32 ビット R[i-1] を 48 ビットに拡張します。 以下に従ってデータ ブロックの最後の 32 ビット R[i-1] を拡張します。ルール。
# 計算を書くことができません。 :(
4 5 6 7 8 9
8 9 10 11 12 13 12 13 14 15 16 17 16 17 18 19 20 21
20 21 22 23 24 25 E [i-1]) と K[i]
; K[i] から E(R[i -1]) を使用して XOR 演算を実行します
2.4.3 E(R[i-1]) xor K[i] を 8 つの 6 ビット ブロックに分割します。 ビット 1 ~ 6 は次のとおりです。
B[1]、ビット 7 ~ 12 は B[2] など、ビット 43 ~ 48 は B[8] になります。
; 前のステップの演算結果を 8 つのブロックに分割し、各ブロックは 6 ビットを持ちます。
という名前の B[1] から B[8] 2.4.4 すべての B[j] の値を S-box に置き換えます。ボックスは 4 ビット幅と見なされます。
;S ボックス内の値をすべての B[j] に置き換えます。S ボックス内のすべての値の幅 (長さ) を置き換えます。 :(
2.4.4.1 B[j] の 1 番目と 6 番目のビットを 2 ビットの値
(m と呼びます) として取得し、置換を調べるために S[j] 内の行を示します。
;B[j]の1番目と6番目のビットをmと名付け、置換時のS[j]の行を示します。
2.4.4.2 B[j] の 2 番目から 5 番目のビットをまとめて、S[j] の列を示す 4 ビット
値 (n と呼びます) として取得し、置換を見つけます
;B[j] を 2 から 5 に置きます。ビットの名前は n で、置換時の S[j] の列を表します。
2.4.4.3 B[j] を S[j][m][n] に置き換えます。
;B[j] を S[j][m][n] に置き換えます。 ️ 8 2 11 15 12 9 7 3 10 5 0
15 12 8 2 4 9 1 7 5 11 3 14 10 0 6 13
S [2]
15 1 8 14 6 11 3 4 9 7 2 13 12 0 5 10
3 13 4 7 15 2 8 14 12 0 1 10 6 9 11 5
0 14 7 11 10 4 13 1 5 12 6 9 3 2 15
13 8 10 1 3 15 4 2 11 6 7 12 0 5 14 9
4 2 8
13 7 0 9 3 4 6 10 2 8 5 14 12 11 15 1
13 6 4 9 8 15 3 0 11 1 2 12 5 10 14 7
1 10 13 0 6 9 8 7 4 15 14 3 11 5 2 12
S[4]
7 13 14 3 0 6 9 10 1 2 8 5 1 12 4 15
13 8 11 5 6 15 0 3 4 7 2 12 1 10 14 9
10 6 9 0 12 11 7 13 15 1 3 14 5 2 8 4
3 15 0 6 10 1 13 8 9 4 5 1 1 12 7 2 14
2 12 4 1 7 10 11 6 8 5 3 15 13 0 14 9
14 11 2 12 4 7 13 1 5 0 15 10 3 9 8 6 4 2 1 11 10 13 7 8 15 9 12 5 6 3 0 14
11 8 12 7 1 14 2 13 6 15 0 9 10 4 5 3
S[6]
12 1 10 15 9 2 6 8 0 13 3 4 14 7 5 11
10 15 4 2 7 12 9 5 6 1 13 14 0 11 3 8
9 14 15 5 2 8 12 3 7 0 4 10 1 13 11 6
4 3 2 12 9 5 5 10 11 14 1 7 6 0 8 13
S[7]
4 11 2 14 15 0 8 13 3 12 9 7 5 10 6 1
13 0 11 7 4 9 1 10 14 3 5 12 2 15 8 6
6 1 4 11 13 12 3 7 14 10 15 6 8 0 5 9 2
6 11 13 8 1 4 10 7 9 5 0 15 14 2 3 12
S[8]
13 2 8 4 6 15 11 1 10 9 3 14 5 0 12 7
1 15 13 8 10 3 7 4 12 5 6 11 0 14 9 2
7 11 4 1 9 12 14 2 0 6 10 13 15 3 5 8
2 1 14 7 4 8 13 15 12 9 0 3 5 6 11
2.4.4.4 ループバック8 つのブロックすべてが置き換えられるまで 2.4.4.1。
; 8 つのデータ ブロックがすべて置き換えられるまで、2.4.4.1 の開始手順を繰り返します。以下に示すように、B[1] から B[8] までの連結を並べ替えます。
;以下の方法で B[1] を B[8] に変更します。
順列 P
16 7 21
29 12 2817
1]。 ]))、ここで、B[j] は E(R[i-1]) xor K[i] の 6 ビット
ブロックです (R[i] の関数は、R[i] =
と記述されます)。 L[i-1 ] xor f(R[i-1], K[i]).)
; L[i-1] を使用して、前のステップの結果に対して XOR 演算を実行します。これにより、次の結果が得られます: R[i] = L[i-1] xor;
P(S[1](B[1])...S[8](B[8]))。ここで、B[j] は 6 ビットのデータ ブロックであり、E(R[i-1]) xor
;K[i] の結果です。 (R[i] の関数は、R[i] = L[i-1] xor f(R[i-1], K[i]) と書くことができます。)
2.4.7 L[i] = R[i -1]
; L[i] = R[i-1]
2.4.8 K[16] が適用されるまで、2.4 から始まる手順を繰り返します。すべてのサブキーが使用されるまでは 1。
# 毎回異なるサブキーを使用して、これを 15 回繰り返します。
2.5 ブロック R[16]L[16] に対して次の置換を実行します。
;R[16]L[16] に対して次の置換を実行します。
‐ ‐ ’ s ’ s ‐ ‐ ‐ 最後の順列 (IP **-1) 39 7 47 15 55 23 63 31 37 5 45 13 5 3 21 61 29 36 44 12 52 20 60 28
35 3 43 11 51 59 27
34 2 42 10 50 18 58 26
33 1 49 17 57 25
これは、des アルゴリズムを使用して 1 つの 64 ビット ブロックを暗号化する方法の説明です
復号するには、同じプロセスを使用します。ただし、キー
K[i] を逆の順序で使用するだけです。つまり、最初の
反復に K[1] を適用する代わりに、2 番目の
反復に K[16 ] を適用します。 K[1].
;上記は、DES アルゴリズムを使用して 64 ビット データ ブロックを暗号化する方法のプロセスです。復号化に関しては、必要なのは
だけです。上記のプロセスでサブキーの順序を逆にするだけです。つまり、サブキー K[1] は暗号化中に使用され、K[16] は復号化プロセス中に使用され、サブキー K[2] は暗号化中に使用され、K[12] は復号化プロセス中に使用されます。 ]。
概要:
;概要
# 以下は、サブキーの生成、暗号化、復号化に関する定型的な説明です。
キースケジュール:
C[0]D[0] = PC1(キー)
for 1 <= i <= 16
C[i] = LS[i](C[i-1])
D[i] = LS[i](D[i-1])
K[i] ] = PC2(C[i]D[i])
暗号化:
L[0]R[0] = IP(プレーンブロック)
for 1 L[i] = R [i-1]
R[i] = L[i-1] xor f(R[i-1], K[i])
暗号ブロック = FP(R[16]L[16])
解読:
R[16]L[16] = IP(暗号ブロック)
for 1 R[i-1] = L[i]
L[i-1] = R[i ] xor f(L[i], K[i])
プレーンブロック = FP(L[0]R[0])
64 ビットを超える暗号化または復号化には、4 つの公式モードがあります
(FIPS で定義)パブ81)。 1 つは、上記の
プロセスをブロックごとに連続して実行することです。これは電子コードブック
(ECB)モードと呼ばれます。より強力な方法は、暗号化の前に、各平文ブロック
と先行する暗号文ブロックとの排他的論理和をとることです。 (最初の
ブロックは、秘密の 64 ビット初期化ベクトル
(IV) と排他的論理和演算されます。)これは、暗号ブロック チェーン (CBC) モードと呼ばれます。他の 2 つの
モードは、出力フィードバック (OFB) と暗号フィードバック (CFB) です。
;64ビットを超える高密度化に対して、(米国)関連邦情報処理標準PUB81では4つの方法が定められている。この方法は、各データブロックに対して上記の操作を継続的に実行する。さらなる
; 高強度の方法は、加圧前に、前述のテキスト ブロックを使用して説明文を実行または操作することです。
データ ブロックのパディングに関しては、いくつかのオプションがあります。1 つは、FIPS PUB 81 によって提案されている 2 つです。
がバイナリデータの場合は、データの
最後のビットの反対のビットでブロックを埋めるか、データがASCIIデータの場合は、ブロックを
ランダムバイトで埋めて、パッドの数に応じたASCII文字を入れます別の手法では、ブロックに
ランダムなバイトを埋め込み、最後の 3 ビットに元のデータ バイト数を格納します。 2 つ目は、(米国) 邦題情報処理標準 PUB 81 によって確立されたものです。たとえば、
; 結果のデータは 2 つあります。 、データ ブロックが ASCII コードの場合、
は、データ ビットの最後にある数値を入力し、最後の文字に埋め込みデータを書き込みます。 ; 文字、そして最後の原データの文字数が最後の 3 ビットに書き込まれます。