OpenSSLが 最終的に版1.0.0に達したので、私はOpenSSLに含まれているデータを暗号化し、解読するのに さまざまな データ暗号化規格(DES)のアプリケーション・プログラミング・インターフェイス(ルーチン)がいかに使用することができるか別の見てみることにした。 実際にOpenSSL DESルーチンを使用するまた方法のインターネットで利用できる簡単な例の欠乏が私あるのでこのポストにいくつかの例を読者をこれらのルーチンで実験するように励ますように含めた。
OpenSSLのlibcryptoのDESルーチンの元の著者はエリックの若者だった。 若者およびティムハドソンは1995年にインターネットにSSLeay (エリックAのためのeay立場、若い)と呼ばれた自由な暗号の図書館のの最初の版を掲示した。 単独でSSLeayで使用される完全な続きの暗号システムを実行するためにどうにかして非常に若者。 それ以来SSLeayの図書館にOpenSSLのなった部分がある。 但しそれにもかかわらず両方マニュアルページおよびソースコードのSSLeayへの頻繁に出くわされた参照。 若者はまだ暗号解読法にかかわり、RSAのEMCの保証部分のために現在働く。
DESの基礎的な情報は暗号解読法の大学の教育課程を忘れていた人のためにおそらくある。 DESは長い時間の間かなりあった。 それはIBMによって既存の主発電機のアルゴリズムへの強化が主にHorst Feistel によって開発されたLuciferを呼んだ と同時に開発された。 それは(今NISTと呼ばれる)標準の国民局が中央政府情報処理の標準書46 (FIPS 46)を出した1977年に標準になった。 その標準はDESが敏感の暗号の保護のために連邦政府の内で使用される、分類していない、コンピュータデータことを指定した。
DESは暗号(英国英語のクラスのメンバーである: ブロック暗号と呼ばれる cyphers)。 ブロック暗号では、暗号の原文からのNビットのブロックは暗号文からのNビットのブロックと取り替えられる。 理想的には入力ブロックと出力ブロック間の関係は完全に任意しかしinvertibleであり。 これは独特な出力ブロックへの地図を描かれる各入力ブロックとの1対1関係を意味する。 数学的に、DESはそれ自身にすべての可能な64ビットのベクトルのセットの地図を描く。 DESの暗号のキーを選ぶことはユーザーが可能な地図作成の1つを選ぶことを可能にする
専門的に言えば、DESは反復的のブロック、プロダクト暗号体系(暗号化アルゴリズム)である。 プロダクト暗号体系は交互になる方法の交差および取り替え操作を混合する。 繰り返しは同じプロシージャの別の繰り返しのための入力として操作の出力の使用を示す。 これはFeistel Feistelの構造かネットワークとして知られている。 Feistelの構造に基づく暗号システムは暗号化および解読両方のために同じ基本アルゴリズムを使用する。 ブロック暗号の大きい割合は、DESを含んで、Festelの構造を使用する。

DESのアルゴリズムの実施はデータ暗号アルゴリズム(DEA)として知られている。 入力ブロックを暗号化するか、または解読するDEAの使用組の交差および取り替え操作の16の繰り返し。 すべての計算はアルゴリズムの 非線形取り替えの部品を提供する取り替え箱(S-boxes)を除いて線形である。 線形アルゴリズムは知られていた暗号の原文の攻撃を使用して容易に壊すことができる。 DEAのS-boxesは効果的に妨げる攻撃(クロウドShannonの`sの拡散の特性。)のこの形態を 円形の数は(16)また重要である。 8円形DEAは選ばれた暗号の原文の攻撃、すなわち差動cryptoanalysisを使用してPCで数分の内に壊すことができる。 DEAが提案されたときに、S-boxesでほとんどのかなりの批評が指示したあった。 S-boxesが引窓を含むかもしれないことを提案された。 DEAの1つの有用な特性はソフトウェアでテーブル索引を使用して(またはハードウェアでその点では)非常に効率的に実行することができることである。 DESは56ビット暗号鍵および64ビットのブロックを使用する。 キー自体は8バイト(64ビット)と指定されるが、各バイトの最後のビットは他の7ビットの奇偶検査として使用される。 円形のキーは48ビット、56ビット暗号鍵から順列の順序によって発生する。
暗号システムへのDESを組み込む複数の方法は可能である。 一般的に、これらはブロックまたは流れ方法に分類することができる。 さらにいくつかの運営方法はFIPS 81の( DESの運営方法 )標準によって指定される。 モードはデータがいかに暗号化され、解読されるか指定する。 これらは次要約される。
電子コードブックモード(ECB)
- 64ビット(すなわちブロック)は一度に数式化される。
- ブロックの発注は検出なしで再配列することができる。
- 暗号の原文のブロックは同じキーのための同じ暗号文のブロックを常に作り出す。
- 間違いは1つの暗号文のブロックだけに影響を与える。
- 登録簿の攻撃に傷つきやすい落胆する使用
モード(CBC)を鎖でつなぐ暗号のブロック
- 64ビットの倍数は一度に数式化される。
- ブロックは再配列することができない。 各暗号文のブロックは流れおよびすべての先行する暗号の原文のブロックによって決まる。
- 暗号の原文のブロックは同じキーのための同じ暗号文のブロックを開始の変数常に作り出し。
- 異なった開始の変数は同じ暗号文に数式化する同じ暗号の原文を防ぐ。
- 間違いは流れおよび続く暗号文のブロックに影響を与える。
暗号フィードバックモード(CFB)
- jのブロックだけ <>
- 小さいjは暗号の原文およびこうしてすばらしい処理の間接費の単位ごとの暗号化のアルゴリズムによってより多くの周期を要求する。
- 暗号の原文のブロックは同じキーのための同じ暗号文のブロックを開始の変数常に作り出し。
- ブロックは再配列することができない。 各暗号文のブロックは流れおよびすべての先行する暗号の原文のブロックによって決まる。
- 異なった開始の変数が同じ暗号文に数式化する同じ暗号の原文を防ぐのに使用されている。
- このモードの強さはキーk (ベストjなら== k)のサイズによって決まる。
- 間違いは流れおよび次の暗号文のブロックに影響を与える。
出力フィードバックモード(OFB)
- jのブロックだけ <>
- 小さいjは暗号の原文およびこうしてすばらしい処理の間接費の単位ごとの暗号化のアルゴリズムによってより多くの周期を要求する。
- 暗号の原文のブロックは同じキーのための同じ暗号文のブロックを開始の変数常に作り出し。
- 異なった開始の変数が同じ暗号文に数式化する同じ暗号の原文を防ぐのに使用されている。
- 鎖でつなぐことの不在はこのモードを特定の攻撃に傷つきやすくさせる。
- 別の開始の可変値は異なった主流れの作成によって同じ暗号文に、数式化する同じ暗号の原文を防ぐ。
- 暗号文の間違いビットにより1ビットだけ解読された暗号の原文の間違う。
- それはself-synchronizingではない。
三重DES ECBモード
- key1と暗号化し、key2と解読し、そしてkey3と再度暗号化しなさい。
- ECBの暗号化に関してはしかし168ビットに変調長さを増加する。
- すべてのキーが同じならそれはちょうど1つのキーとの一度暗号化と同等である。
- 最初そして最後のキーが同じなら、変調長さは112ビットである。
- 3つのキーがすべて同じなら、これは正常なECBモードと効果的に同じである。
三重DES CBCモード
- key1と暗号化し、key2と解読し、そして次にkey3と暗号化しなさい。
- CBCの暗号化に関してはしかし三重DES ESBモードと同じ制限の168ビットに変調長さを増加する
私達の最初例に基本的なDESの暗号化ルーチン、DES_ecb_encryptを()使用しか、電子コード一覧表(ECB)モードに暗号の原文の単一の64ビットのブロックを暗号化しか、または解読する方法を示されている。 暗号化の議論がDES_ENCRYPTなら、入力(暗号の原文)は出力(暗号文)に指定key_scheduleを使用して暗号化される。 暗号化の議論がDES_DECRYPTなら、入力(暗号文)は出力(暗号の原文)に解読される。 入出力が重複するかもしれないことに注目しなさい。
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <openssl/des.h>
#include <openssl/rand.h>
#define BUFSIZE 64
int main(void)
{
unsigned char in[BUFSIZE], out[BUFSIZE], back[BUFSIZE];
unsigned char *e = out;
DES_cblock key;
DES_cblock seed = {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10};
DES_key_schedule keysched;
memset(in, 0, sizeof(in));
memset(out, 0, sizeof(out));
memset(back, 0, sizeof(back));
RAND_seed(seed, sizeof(DES_cblock));
DES_random_key(&key);
DES_set_key((C_Block *)key, &keysched);
/* 8 bytes of plaintext */
strcpy(in, "HillTown");
printf("Plaintext: [%s]\n", in);
DES_ecb_encrypt((C_Block *)in,(C_Block *)out, &keysched, DES_ENCRYPT);
printf("Ciphertext:");
while (*e) printf(" [%02x]", *e++);
printf("\n");
DES_ecb_encrypt((C_Block *)out,(C_Block *)back, &keysched, DES_DECRYPT);
printf("Decrypted Text: [%s]\n", back);
return(0);
}
C_Blockの使用に注意しなさい。 このポストの例はそれが私が使用に使用されるものであるのでC_Blockを使用する。 現代プラットホームのために新しいコードを書けば、C_Blockかdes_cblockよりもむしろDES_cblockを使用するべきである。 DES_cblockのdefintion、すなわちtypedefの無署名の木炭DES_cblock [8]についてはdes.hを見なさい。
プログラムが編集され、実行される場合のここに出力。
$ gcc -o example1 example1.c -lcrypto $ ./example1 Plaintext: [HillTown] Ciphertext: [34] [bc] [85] [30] [14] [95] [43] [00] Decrypted Text: [HillTown] $
2部がDESの暗号化の使用へあることを上記のコードを検査して見る。 第1キーからのDES_key_scheduleの生成である、第2実際の暗号化または解読である。 DESのキーはタイプDES_cblock奇数パリティーの8バイトから成っているである。 各バイトの最下位のビットは同等ビットである。 主スケジュールは暗号化プロセスを促進するのに使用されているキーの拡大されたプラットホーム依存した用紙である。 例は播かれたPRNG ( RAND_seed使用する())を 任意64ビットDESのキーを発生させるため。 私が明確に例が使用するすべての貯蔵を0点規正することに気づきなさい; OpenSSLの図書館常務を使用する場合のよい常に考え。 暗号文のサイズが暗号の原文と同じであることを出力を検査して、見る。 これはブロック暗号の特徴である。 この例を編集し、動かしたら、私が事実が原因にという例の使用任意に発生させたキーなったのと同じ暗号文を得ないことに注目しなさい。
私達の次の例三重DESモードを示したものだ。 どういうわけか多くの人々はFIPS-46が三重DESのために実際に2つのモードを指定すること気づいていない:
- エーデ(暗号化解読暗号化しなさい)ところで暗号文= Ek3 (Dk2 (Ek1 (暗号の原文)))
- EEE (暗号化暗号化暗号化しなさい)ところで暗号文= Ek3 (Ek2 (Ek1 (pliantext)))
EkおよびDkがそれぞれDESの暗号化および解読を表示するところ。 さらに、ANSI X9.52は三重DESのための3つの主選択を定義する:
- k1! = k2! = k3
- k1! = k2、k1 = k3、k2! = k3
- k1 = k2 = k3
第3選択は三重DESをDESとbackwardly互換性があるようにする。 推薦された使用法モードは、三重DESのためのFIPS-46ごとに、3つの独自に発生させたキー、合計のすなわち168のキービットのEEEまたはエーデである。 OpenSSLはエーデモードを使用する。
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <openssl/des.h>
#include <openssl/rand.h>
#define BUFSIZE 1024
int main(void)
{
unsigned char in[BUFSIZE], out[BUFSIZE], back[BUFSIZE];
unsigned char *e = out;
int i;
DES_cblock key1, key2, key3;
DES_cblock seed = {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10};
DES_key_schedule ks1, ks2, ks3;
memset(in, 0, sizeof(in));
memset(out, 0, sizeof(out));
memset(back, 0, sizeof(back));
RAND_seed(seed, sizeof(DES_cblock));
DES_random_key(&key1);
DES_random_key(&key2);
DES_random_key(&key3);
DES_set_key((C_Block *)key1, &ks1);
DES_set_key((C_Block *)key2, &ks2);
DES_set_key((C_Block *)key3, &ks3);
/* 64 bytes of plaintext */
strcpy(in, "Now is the time for all men to stand up and be counted");
printf("Plaintext: [%s]\n", in);
for (i = 0; i < 63; i += 8) {
DES_ecb3_encrypt((C_Block *)(in + i),(C_Block *)(out + i), &ks1, &ks2, &ks3, DES_ENCRYPT);
}
printf("Ciphertext:");
while (e++) printf(" [%02x]", *e++);
printf("\n");
for (i = 0; i < 63; i += 8) {
DES_ecb3_encrypt((C_Block *)(out + i),(C_Block *)(back + i), &ks1, &ks2, &ks3, DES_DECRYPT);
}
printf("Decrypted Text: [%s]\n", back);
exit(0);
}
見ることができるようにこの例の使用3つのキー(k1! = k2! 三重DESを使用する推薦された方法はであるかどれ= k3)。 この例が編集され、実行されるとき出力はここにある:
[fpm@ultra ~]$ ./example2 Plaintext: [Now is the time for all men to stand up and be counted] Ciphertext: [b4] [31] [40] [aa] [41] [7d] [fc] [72] [4b] [f7] [46] [b5] [24] [83] [95] [03] [38] [1a] [50] [4e] [65] [5e] [83] [19] [b4] [0f] [74] [8b] [0c] [de] [5f] [34] [bf] [ee] [65] [4a] [b1] [0d] [33] [b4] [db] [cd] [02] [2c] [6c] [39] [7e] [57] [0d] [99] [18] [69] [23] [56] [fb] [00] Decrypted Text: [Now is the time for all men to stand up and be counted] [fpm@ultra ~]$
次の例モードを鎖でつなぐ暗号のブロックを示したものだ。 このモードで各ブロックは暗号化の前に前のcipherblockとのXOREDである。
暗号の原文の変更が暗号文で永久に広がるので、暗号化は平行にすることができない。 最初のブロックのために私達はinitiallizationのベクトル (ivec )から始まる。 それが初期設定のベクトルとしてゼロベクトルから始まることは珍しくないことに注目しなさい。 DES_cbc_encrypt ()およびlibcryptoにDES_ncbc_encryptが両方()あることに注目しなさい。 私は使用するncbc版だけを推薦する(nは新しいを意味する)。 これらの機能についてはOpenSSL DESのマニュアルページの虫セクションおよびソースコードを見なさい。
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <openssl/des.h>
#include <openssl/rand.h>
#define BUFSIZE 512
int main(void)
{
unsigned char in[BUFSIZE], out[BUFSIZE], back[BUFSIZE];
unsigned char *e = out;
int len;
DES_cblock key;
DES_cblock seed = {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10};
DES_cblock ivsetup = {0xE1, 0xE2, 0xE3, 0xD4, 0xD5, 0xC6, 0xC7, 0xA8};
DES_key_schedule keysched;
DES_cblock ivec;
memset(in, 0, sizeof(in));
memset(out, 0, sizeof(out));
memset(back, 0, sizeof(back));
RAND_seed(seed, sizeof(DES_cblock));
DES_random_key(&key);
DES_set_odd_parity(&key);
if (DES_set_key_checked((C_Block *)key, &keysched))
{
fprintf(stderr, "ERROR: Unable to set key schedule\n");
exit(1);
}
/* 64 bytes of plaintext */
strcpy(in, "Now is the time for all men to stand up and be counted");
printf("Plaintext: [%s]\n", in);
len = strlen(in);
memcpy(ivec, ivsetup, sizeof(ivsetup));
DES_ncbc_encrypt(in, out, len, &keysched, &ivec, DES_ENCRYPT);
printf("Ciphertext:");
while (*e) printf(" [%02x]", *e++);
printf("\n");
memcpy(ivec, ivsetup, sizeof(ivsetup));
DES_ncbc_encrypt(out, back, len, &keysched, &ivec, DES_DECRYPT);
printf("Decrypted Text: [%s]\n", back);
exit(0);
}
私が暗号文をことを解読する前にivecを初期設定をやり直すことに注目しなさい。 ivecを初期設定をやり直さなければあなたの解読されたテキストは不正確である。
次の例3つのキーの外の三倍CBC DESの暗号化を実行するのにDES_ede3_ncbc_encryptを()使用する。 これはCBCモードの中の各DES操作がC=E (ks3、D (ks2、E (ks1、M)))であることを意味する。 これはSSLによってモード使用されるである。
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <openssl/des.h>
#include <openssl/rand.h>
#define BUFSIZE 512
int main(void)
{
unsigned char in[BUFSIZE], out[BUFSIZE], back[BUFSIZE];
unsigned char *e = out;
int len;
DES_cblock key1, key2, key3;
DES_cblock seed = {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10};
DES_cblock ivsetup = {0xE1, 0xE2, 0xE3, 0xD4, 0xD5, 0xC6, 0xC7, 0xA8};
DES_cblock ivec;
DES_key_schedule ks1, ks2, ks3;
memset(in, 0, sizeof(in));
memset(out, 0, sizeof(out));
memset(back, 0, sizeof(back));
RAND_seed(seed, sizeof(DES_cblock));
DES_random_key(&key1);
DES_random_key(&key2);
DES_random_key(&key3);
DES_set_key((C_Block *)key1, &ks1);
DES_set_key((C_Block *)key2, &ks2);
DES_set_key((C_Block *)key3, &ks3);
/* 64 bytes of plaintext */
strcpy(in, "Now is the time for all men to stand up and be counted");
printf("Plaintext: [%s]\n", in);
len = strlen(in);
memcpy(ivec, ivsetup, sizeof(ivsetup));
DES_ede3_cbc_encrypt(in, out, len, &ks1, &ks2, &ks3, &ivec, DES_ENCRYPT);
printf("Ciphertext:");
while (*e) printf(" [%02x]", *e++);
printf("\n");
len = strlen(out);
memcpy(ivec, ivsetup, sizeof(ivsetup));
DES_ede3_cbc_encrypt(out, back, len, &ks1, &ks2, &ks3, &ivec, DES_DECRYPT);
printf("Decrypted Text: [%s]\n", back);
exit(0);
}
暗号文を解読する前にivecを初期設定をやり直す必要性に注意しなさい。 これをしなければ、結果として生じる暗号の原文の最初の64ビットは不正確である。
次の例出力フィードバックの覆うことと鎖でつなぐトリプルDESの暗号のブロックと呼ばれるCBC モードの変更された形態の使用を示したものだ。 このモードは各三重DES暗号化操作の中間出力とのXOREDである秘密の覆う価値の導入を通して64ビットのDESのブロックサイズを開発する辞書の攻撃および一致の暗号文のに対してより強い保護を攻撃提供する。 しかしApparantlyはEli BihamおよびLars Knudsenこのモードの攻撃を開発したが、多くの仕事を要求する。
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <openssl/des.h>
#include <openssl/rand.h>
#define BUFSIZE 512
#define CBCM_ONE
int main(void)
{
unsigned char in[BUFSIZE], out[BUFSIZE], back[BUFSIZE];
unsigned char *e = out;
int len;
DES_cblock key1, key2, key3;
DES_cblock seed = {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10};
DES_cblock ivecstr = {0xE1, 0xE2, 0xE3, 0xD4, 0xD5, 0xC6, 0xC7, 0xA8};
DES_cblock ivec2, ivec1;
DES_key_schedule ks1, ks2, ks3;
memset(in, 0, sizeof(in));
memset(out, 0, sizeof(out));
memset(back, 0, sizeof(back));
RAND_seed(seed, sizeof(DES_cblock));
DES_random_key(&key1);
DES_random_key(&key2);
DES_random_key(&key3);
DES_set_key((C_Block *)key1, &ks1);
DES_set_key((C_Block *)key2, &ks2);
DES_set_key((C_Block *)key3, &ks3);
/* 64 bytes of plaintext */
strcpy(in, "Now is the time for all men to stand up and be counted");
printf("Plaintext: [%s]\n", in);
memcpy(ivec2, ivecstr, sizeof(ivecstr));
memset(ivec1,'\0',sizeof(ivec2));
len = strlen(in) + 1;
#ifdef CBCM_ONE
DES_ede3_cbcm_encrypt(in, out, len, &ks1, &ks2, &ks3, &ivec2, &ivec1, DES_ENCRYPT);
#else
DES_ede3_cbcm_encrypt(in, out, 16, &ks1, &ks2, &ks3, &ivec2, &ivec1, DES_ENCRYPT);
DES_ede3_cbcm_encrypt(&in[16], &out[16],len-16, &ks1, &ks2, &ks3, &ivec2, &ivec1, DES_ENCRYPT);
#endif
printf("Ciphertext:");
while (*e) printf(" [%02x]", *e+);
printf("\n");
len = strlen(out) + 1;
memcpy(ivec2, ivecstr, sizeof(ivecstr));
memset(ivec1,'\0',sizeof(ivec2));
DES_ede3_cbcm_encrypt(out, back, len, &ks1, &ks2, &ks3, &ivec2, &ivec1, DES_DECRYPT);
printf("Decrypted Text: [%s]\n", back);
exit(0);
上記の例のshowns暗号の原文を暗号化するためのまた逆も同様2つの変化。 ツーステップのアプローチは状況によっては有用である。
次の例暗号のフィードバック(CFB)モードの使用を示したものだ。 CFBは1ビットモードが選ばれればCBCの近親者であるが、self-synchronizingストリーム暗号である。
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <openssl/des.h>
#include <openssl/rand.h>
#define BUFSIZE 256
#define CFBMODE 1
int main(void)
{
unsigned char in[BUFSIZE], out[BUFSIZE], back[BUFSIZE];
unsigned char *e = out;
int len;
DES_cblock key;
DES_cblock seed = {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10};
DES_cblock ivecstr = {0xE1, 0xE2, 0xE3, 0xD4, 0xD5, 0xC6, 0xC7, 0xA8};
DES_cblock ivec;
DES_key_schedule ks;
memset(in, 0, sizeof(in));
memset(out, 0, sizeof(out));
memset(back, 0, sizeof(back));
RAND_seed(seed, sizeof(DES_cblock));
DES_random_key(&key);
DES_set_key((C_Block *)key, &ks);
/* 11 bytes of plaintext */
strcpy(in, "Philippines");
printf("Plaintext: [%s]\n", in);
memcpy(ivec, ivecstr, sizeof(ivecstr));
len = strlen(in);
DES_cfb_encrypt(in, out, CFBMODE, len, &ks, &ivec, DES_ENCRYPT);
printf("Ciphertext:");
while (*e) printf(" [%02x]", *e+);
printf("\n");
len = strlen(out);
memcpy(ivec, ivecstr, sizeof(ivecstr));
DES_cfb_encrypt(out, back, CFBMODE, len, &ks, &ivec, DES_DECRYPT);
printf("Decrypted Text: [%s]\n", back);
exit(0);
}
例は初期設定のベクトルおよびDESのキーのためにCBF64モードをまた使用する、はじめて、使用するASCIIのひもをここにあり。
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <openssl/des.h>
#define BUFSIZE 256
int main(void)
{
unsigned char in[BUFSIZE], out[BUFSIZE], back[BUFSIZE];
unsigned char *e = out;
int len;
int n = 0;
static char *keystr = "0123456789abcdef";
static char *ivecstr = "0123456789abcdef";
DES_cblock ivec;
DES_key_schedule ks;
memset(in, 0, sizeof(in));
memset(out, 0, sizeof(out));
memset(back, 0, sizeof(back));
strcpy(in,"Now is the time for all.");
DES_set_key((C_Block *)keystr, &ks);
printf("Plaintext: [%s]\n", in);
memcpy(ivec, (C_Block *)ivecstr, sizeof(ivec));
len = strlen(in) + 1;
DES_cfb64_encrypt(in, out, len, &ks, &ivec, &n, DES_ENCRYPT);
printf("Ciphertext:");
while (*e) printf(" [%02x]", *e++);
printf("\n");
memcpy(ivec, (C_Block *)ivecstr, sizeof(ivec));
DES_cfb64_encrypt(out, back, len, &ks, &ivec, &n, DES_DECRYPT);
printf("Decrypted Text: [%s]\n", back);
exit(0);
}
キーにひもを変えるDES_string_to_keyの使用に()注意しなさい。 入れられたひもは奇数パリティーによってがそうそこにDES_set_odd_parityを実施する必要性ではない少なくとも16組の特性長さが.DES_string_to_key ()セットべきである()。
次の例8ビットOFBモードの使用を示したものだ。 このモードは解読された暗号の原文の付加的な間違いを引き起こすために暗号文の間違いが拡張されない付加的なストリーム暗号である。 従って暗号文の間違いのシングル・ビットにより1ビットだけ解読された暗号の原文の間違う。 OpenSSLのマニュアルページに従って、このモードは暗号の原文の小さいサイズのためにだけ使用するべきである。 numbitsでの実験およびDESのマニュアルページの虫セクションから、私はnumbitsのために8という値を常に使用することを提案する。
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <openssl/des.h>
#include <openssl/rand.h>
#define BUFSIZE 256
int main(void)
{
unsigned char in[BUFSIZE], out[BUFSIZE], back[BUFSIZE];
unsigned char *e = out;
char *keystr = "Philippines06235";
int len, n, result;
DES_cblock key;
DES_cblock ivecstr = {0xE1, 0xE2, 0xE3, 0xD4, 0xD5, 0xC6, 0xC7, 0xA8};
DES_cblock ivec;
DES_key_schedule ks;
memset(in, 0, sizeof(in));
memset(out, 0, sizeof(out));
memset(back, 0, sizeof(back));
DES_string_to_key(keystr, &key);
if ((result = DES_set_key_checked((C_Block *)key, &ks)) != 0) {
if (result == -1) {
printf("ERROR: key parity is incorrect\n");
} else {
printf("ERROR: weak or semi-weak key\n");
}
exit(1);
}
strcpy(in,"The Chocolate Hills of Bohol are wonderful.");
printf("Plaintext: [%s]\n", in);
memcpy(ivec, ivecstr, sizeof(ivecstr));
len = strlen(in);
printf("Plaintext Length: %d\n", len);
DES_ofb_encrypt(in, out, 8, len, &ks, &ivec);
n = 0;
printf("Ciphertext:");
while (*e) {
printf(" [%02x]", *e++);
n++;
}
printf("\n");
printf("Ciphertext Length: %d\n", n);
len = strlen(out);
memcpy(ivec, ivecstr, sizeof(ivecstr));
DES_ofb_encrypt(out, back, 8, len, &ks, &ivec);
printf("Decrypted Text: [%s]\n", back);
exit(0);
}
このポストの最終的な例は暗号化および解読を行うのにede3_ofb64_encryptを()使用する。 それはまた外的なファイルからの暗号の原文を読取る。 事を簡単にし、例を短くするために、私はk1 = k2 = k3置いた。 例を変更するように場合を支えるために私があなたまでそれをk1残す! = k2! = k3。
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <openssl/des.h>
#define BUFSIZE 1024
int main(int argc, char *argv[])
{
unsigned char in[BUFSIZE], out[BUFSIZE], back[BUFSIZE];
char buf[201];
char *keystr = "Victoria Harbour";
unsigned char *e = out;
FILE *fin;
int i, num, len, result;
int n = 0;
DES_cblock key;
DES_cblock ivsetup = {0xE1, 0xE2, 0xE3, 0xD4, 0xD5, 0xC6, 0xC7, 0xA8};
DES_key_schedule ks;
DES_cblock ivec;
if (argc != 2) {
printf("ERROR: plaintext filename required\n");
exit(1);
}
memset(in, 0, sizeof(in));
memset(out, 0, sizeof(out));
memset(back, 0, sizeof(back));
DES_string_to_key(keystr, &key);
if ((result = DES_set_key_checked((C_Block *)key, &ks)) != 0) {
if (result == -1) {
printf("ERROR: key parity is incorrect\n");
} else {
printf("ERROR: weak or semi-weak key\n");
}
exit(1);
}
fin = fopen(argv[1], "r");
if (!fin) {
printf(" ERROR: opening input file\n");
exit(1);
}
while(fgets(buf, 200, fin) != NULL) {
strcat(in, buf);
}
fclose(fin);
printf("Plaintext: [%s]\n", in);
len = strlen(in);
printf("Plaintext Length: %d\n", len);
memcpy(ivec, ivsetup, sizeof(ivsetup));
num = 0;
for (i = 0; i < len; i++) {
DES_ede3_ofb64_encrypt(&(in[i]), &(out[i]), 1, &ks, &ks, &ks, &ivec, &num);
}
n = 0;
printf("Ciphertext:");
while (*e) {
printf(" [%02x]", *e++);
n++;
}
printf("\n");
printf("Ciphertext Length: %d\n", n);
memcpy(ivec, ivsetup, sizeof(ivsetup));
num = 0;
for (i = 0; i < len; i++) {
DES_ede3_ofb64_encrypt(&(out[i]), &(back[i]), 1, &ks, &ks, &ks, &ivec, &num);
}
printf("Decrypted Text: [%s]\n", back);
exit(0);
}
出力例はここにある:
$ echo -n "Now is the time to finish this post" > plaintext $ ./example9 plaintext Plaintext: [Now is the time to finish this post] Plaintext Length: 35 Ciphertext: [92] [cb] [29] [fe] [aa] [94] [d7] [ba] [07] [a5] [8f] [78] [4f] [13] [fa] [c4] [4f] [22] [0d] [fd] [b7] [33] [81] [3e] [3a] [e4] [f5] [c6] [52] [c9] [2b] [4f] [d5] [b8] [00] Ciphertext Length: 35 Decrypted Text: [Now is the time to finish this post] $
それで、私は私がほとんどの読者のための十分な細部のOpenSSL v1.0 DESルーチンをカバーしたことを考える。 他のいくつかのルーチンがあるが、これらはまれに上の例で使用されるルーチンのわずかな変化使用されるか、またはである。 des_から始まるDESルーチンへの多くの参照に出くわすことができる。 これらはDES_ルーチンと本質的に同じであるが、libcryptoのより古い版からある。 DES_への移動は前に数年行われた。 利用できればルーチンのDES_版を常に使用するべきである。
あなたの新しい知識と武装させていて、立ち去り、あなたの適用内のDESを使用今べきである。 このポストに含まれているソースコードを使用すること自由に感じなさい。 DESについての詳細を学びたいと思えばダグラスStinsonは本のCrytography彼の理論および練習(ISBN 0-8493-8521-0)の章の第3すばらしい仕事をする。 Cのソースコードの多くが付いているもう一つの優秀な本は、ブルースSchneirの加えられた暗号解読法(ISBN 0-471-59756-2)である。 残念ながら、現在OpenSSLのマニュアルページは精々粗末率直な不正確万一のことがあってもであり、従って頻繁にあなた自身をlibcryptoのソースコードを検査することを見つけるかもしれない。 関連したDESコードすべては../crypto/desのサブディレクトリーにある。
楽しみなさい!



























貴重、
それは興奮し、美しいコードである。 、多くの人がOpenSLLを使用できる事の助けはっきり示し、説明した。
!そんなにありがとう!!
NguyenタイのThuan。
Sai Gon
ベトナム
こんにちは、
この素晴らしいポストをありがとう。
私はまた質問を有する!
暗号のfuncs (例えばDES_ecb3_encrypt)の上のそれを引き起こすかもしれない何により異なったOSのプラットホームの同じ結果を戻してはいけない、
Solaris (SunOS 5.10)、Linux 32,64または多分UbuntuまたはCentos等のようにか。
それなら、私達を全然重要ではないOSを言うことを許可しなさい、そうすれば論理的な仮定は次のとおりである:
1. openssl版。(か。か。、しかし全インターネットについての何、この1のための非常に低い確率。 )
2.初期設定は出る
DESのキーが使用することができる前に(それは建築の扶養家族に変えられなければならない
DES_set_key_checked ()またはDES_set_key_unchecked ()機能によるDES_key_schedule。 )
私はそれについて非常に混同している。
私は同じk1、k2、k3の同じCコードのDES_ecb3_encryptそしてDES_set_key_uncheckedを()使用する。
よろしく、
Ivan
こんにちは再度、
Ofcourse、私はDES_ecb3_encrypt以外わかっていることクリプトalgかモード
(きちんと使用されたら)決して同じcypherの結果を発生させてはいけない。
Ivan。
こんにちは、
解決する問題:)。
暗号の図書館のインターオペラビリティについての疑い無し:)。
ofcourseは問題の性質人間:))だった)。
DES_set_key_unchecked方法の誤用
引き起こされた間違ったencか12月は生じる。
よろしく、
Ivan
Ivan、
嬉しいそれを解決した。
私はDESの速い個人指導を必要とし、opensslおよびあなたのブログの3DESルーチンははっきり、整然としたおよびちょうど右の詳細レベル書かれていた。 本当にありがとう。
しかしあなたのプログラムは助けのビットを使用できる。
最初のプログラムだけ(des.c)考慮。
可変的なeは誤用される、
暗号化されたブロックのバイト0は印刷されない
引きずるNULは常に印刷される
そして期待する理由がとNULない
暗号化されたブロックの部分があってはいけない。
データタイプDES_Cblockがキーを宣言するのに使用されているがDES_ecb_encryptへの呼出しで、変数は投げられる(C_Block *)。 C_blockは外見上DES_Cblockのより古い形態である。
、緩衝は私が混同を見つけた64バイトに、および背部DESが64のビットブロックを使用するので、割振られる。
私は誰か他の人が帰りの価値のDES_set_key_checkedそして点検よりもむしろDES_set_keyの使用について既にコメントしたことを見る。
私は乱数発電機の使用を理解しない。 プログラムは使用するために8バイトをように乱数種定義し、次にDES_random_keyから8バイトのキーを得る。 乱数発電機を播いた後、返される値は任意べきではない。 (私はコードに従がってprngについてのコメントを、私どうしても理解しない意思を読んだ)
ラリー、
間(*e++)のループのよい捕獲物。 固定。 それは夜にそれを十分に再度テストしないで出版物のためのコードを遅くきれいに片付けるとき起こることができるものがである!
私はDES_Cblockがあなたの部分のタイプエラーであり、実際にDES_cblockを言うことを意味したことを仮定する。 DES_cblockはdes_cblockとしてそしてそのC_Block前に最も最近の化身のあった前に知られていたである。 これらのどれでもまだ有効である。 私はC_Blockの使用にちょうど使用される。
BUFSIZEはの、および入力テキスト、暗号化されたテキストおよび非暗号化のテキストを貯えるのに使用される背部緩衝を示す。 ひも「HillTown」は0を含む9バイトを取る従って例1の目的のために、私は9.にBUFSIZEを減らしたかもしれない。 DESのinternalsとすることを何も。
DES_set_key_checkedi ()および帰りの価値、両方の点検よりもむしろDES_set_keyの使用に関して()このポストの例で使用される。 私はDES_set_key_checkedを常に使用するべきであることあなたの主張がなら私の応答は簡単である- DES_set_key APIなぜそれからあるか。 どちらかのAPIを使用する正当な理由がある。
優秀な報告およびすばらしい例。 これは実際に役人のOpenSSLの続きが種類のこれのようなドキュメンテーションに欠けているように私を助けた。 私は容易に検討の後で私の仕事を実行できた。 ありがとう。
こんにちは。
私を助けなさい。 私のコード:
intのnewTextLength = newText.length (); /////主no.2 - >主no.1
のため(int I = 0; I < lenOrgTxt; I += 8)
{
DES_ecb3_encrypt ((DES_cblock *) (unsignedCharTextForEncrypt+i)、(DES_cblock* (encryDES+i)、
&keySched1、&keySched2、&keySched1、DES_ENCRYPT);
}
私のテキストの長さが120と等しいかまたはそれ以下である時。 暗号化すれば解読プロセスは正しく働いている。
しかし時私のテキストの長さが120より大きい(128または。 256)! プロセスを暗号化した後、encryDESの長さは36常にであり、解読プロセスは間違っている!
この方法の私のテキストは120べきであるか。 この方法で入力テキストをあらゆる限定持っているか。
こんにちは、
私は平文パスワードを暗号化し、解読するのにDES_ecb3_encryptを使用している。
それはあるパスワードをうまく使用する。
しかしパスワード「Imate@005 ″ [MATRIXSE]、Key2 = []、再度私に「のImate@005 ″を与えないKey3 = []およびそれ、decypt私がそれをとのKey1 =暗号化する場合のと与える私にがらくたの価値を。
plsは助ける。
続くことは私のコードである:
int TDES_Decrypt (木炭の*sCipher、木炭の*sKey、木炭の*sPlainText)
{
fplogは= fopen (「3DES1.log」」、a」);
fprintf (fplog」、\ n \ n \ n .................. TDES_Decryptの中の.......................... \ n」);
fprintf (fplog」、\ nは前部分からのパスワードを暗号化した:: [%s]:: [%d] ...... 「、sCipherは、strlen (sCipher));
fprintf (fplog」、\ nは形態の前部分を調整する:: [%s]:: [%d] .......」、sKeyは、strlen (sKey));
int iRetVal=0;
木炭SessionKeyFE [KEY_LEN_SESSION];
DES_cblock key1;
DES_cblock key2;
DES_cblock key3;
DES_cblockのinBuffer;
DES_cblockのtempBuffer;
DES_key_schedule *ks1;
DES_key_schedule *ks2;
DES_key_schedule *ks3;
memcpy (SessionKeyFEのsKey、KEY_LEN_SESSION);
memset (&key1の「`、DES_KEY_SZ);
memcpy (&key1の&SessionKeyFE [0]、DES_KEY_SZ);
fprintf (fplog、前部分からの」\ nキー1:: [%s]:: [%d] 「、key1は、strlen (key1));
memset (&key2の「`、DES_KEY_SZ);
memcpy (&key2の&SessionKeyFE [8]、DES_KEY_SZ);
fprintf (fplog、前部分からの」\ nキー2:: [%s]:: [%d] ......」、key2は、strlen (key2));
memset (&key3の「`、DES_KEY_SZ);
memcpy (&key3の&SessionKeyFE [16]、DES_KEY_SZ);
fprintf (fplog、前部分からの」\ nキー3:: [%s]:: [%d] 「、key3は、strlen (key3));
ks1= (空間*)のmalloc (DES_SCHEDULE_SZ);
DES_set_key_unchecked (key1、ks1);
ks2= (空間*)のmalloc (DES_SCHEDULE_SZ);
DES_set_key_unchecked (key2、ks2);
ks3= (空間*)のmalloc (DES_SCHEDULE_SZ);
DES_set_key_unchecked (key3、ks3);
memset (&inBuffer、「`、DES_KEY_SZ);
memset (&tempBuffer、「`、DES_KEY_SZ);
fprintf (fplog」、\ n \ n DES_KEY_SZ = [%dの] \ n」、DES_KEY_SZ);
memcpy (&inBuffer、sCipher、DES_KEY_SZ);
fprintf (fplog、inBufferの」\ nは\ nの............価値次のとおりである:: [%s]::。[%d] ......」、inBufferは、strlen (inBuffer));
DES_ecb3_encrypt (&inBuffer、&tempBuffer、ks1、ks2、ks3、DES_DECRYPT);
memcpy (sPlainText、&tempBuffer、DES_KEY_SZ);
fprintf (fplog」、\解読されたパスワードのn____のパート1:: [%s]:: [%d]….」、sPlainTextは、strlen (sPlainText));
memset (&inBuffer、「`、DES_KEY_SZ+1);
memset (&tempBuffer、「`、DES_KEY_SZ+1);
memcpy (&inBuffer、sCipher + 8、DES_KEY_SZ);
fprintf (fplog、inBufferの」\ nは\ nの............価値次のとおりである:: [%s]::。[%d] ......」、inBufferは、strlen (inBuffer));
DES_ecb3_encrypt (&inBuffer、&tempBuffer、ks1、ks2、ks3、DES_DECRYPT);
memcpy (sPlainText + 8の&tempBuffer、DES_KEY_SZ);
fprintf (fplog」、\解読されたパスワードのn____のパート2:: [%s]:: [%d]….」、tempBufferは、strlen (tempBuffer));
fprintf (fplog」、\ n____の最終的な平文パスワード:: [%s]:: [%d]….」、sPlainTextは、strlen (sPlainText));
放しなさい(ks1); 放しなさい(ks2); 放しなさい(ks3);
fclose (fplog);
帰りのiRetVal;
}