シンプルなデータ暗号化と復号化アルゴリズムの実装方法を教えます

シンプルなデータ暗号化と復号化アルゴリズムの実装方法を教えます

この記事では、シンプルだが実用的な暗号化方式を実装する方法を紹介します。

実際のプロジェクト開発におけるデータ暗号化のプロセスを誰もが理解できるようにします。

1. ネットワーク通信のための一般的な暗号化プロセス

暗号化アルゴリズムは数多く存在し、実際の実装プロセスも大きく異なります。

下の図は、ネットワーク通信暗号化の一般的な応用シナリオです。

暗号機に関するいくつかの指示:

  • クライアントとサーバーの両方が暗号化マシンをセットアップできます(キーを生成できる限り、ソフトウェアでもハードウェアでも、ローカルでもサーバー上でもかまいません)。
  • キー生成コードと同期コードの両方が暗号マシンによって生成されるキーシーケンスに影響します。
  • キー生成コードと同期コードが同じ場合、暗号は同じキーシーケンスを生成します。暗号化側と復号化側の両方が、キーが生成された順序を覚えておき、復号化するデータと同じ数のキーを申請する必要があります。

上図に示すように、C/Sアーキテクチャに基づくサーバーとクライアントの通信モデルは、

以下は、クライアントが暗号化された暗号文をサーバーに送信する場合の C/S 対話のプロセスです。

1サーバーは鍵暗号文を送信する

まず、サーバーとクライアントの両方がデフォルトのキーを保存します

サーバーはランダムにキーキージェネレータを生成し、デフォルトのキーを使用してキージェネレータを暗号化し、キー暗号文を生成します。

クライアントはコマンドを通じて定期的に鍵暗号文を要求するか、サーバーが定期的に鍵暗号文を送信することができる。

クライアントはキー暗号文を受け取った後、デフォルトのキーを使用してそれを復号化し、平文のキー生成を取得することもできます。

2. クライアントがデータを暗号化する

データを送信する前に、クライアントはまず同期コードを生成する。

同期コードとキージェネレータを暗号機に設定し、暗号機から特定の長さのキーを申請します。

平文とキーを特定のアルゴリズム(通常はXOR)で暗号化し、データ暗号文を生成します。

3. クライアントは同期コードとデータ暗号文を送信する

クライアントはデータの暗号文と同期コードの平文をサーバーに送信する

サーバーは同期コードを抽出する

4. サーバーはデータを受信し、復号化する

サーバーは暗号機にキージェネレータと同期コードを設定し、一定数のキーを申請する。

サーバーは鍵に従って暗号文を復号し、対応する平文を取得する。

現時点では、サーバーとクライアントは同じキージェネレータと同期コードを使用しているため、両者が適用するキーシーケンスは同じである必要があります。

2. 関数の実装

以下は、Yikoujun によって実装された暗号化アルゴリズムのいくつかの関数プロトタイプと機能説明です。これらの関数は基本的に、最初のセクションの機能を実装します。

1. 暗号化キー関数request_keyを申請する

  1. int request_key( int sync, int key_num, char  [])
  2. 関数:
  3. データを暗号化するための鍵を一定数暗号機に申請します。新しいキージェネレータが設定されていない場合、生成されたパスワードは順番に生成されます。鍵が申請されるたびに、最後に生成された鍵のオフセットが記録されます。次に鍵が申請されると、前回の位置から鍵が割り当てられ続けます。
  4. パラメータ:
  5. sync: 同期コード。暗号はこの同期に基づいてランダムなキーシーケンスを生成します。
  6. key_num: 要求されたキーの数
  7. key : 要求されたキーストレージのキャッシュ
  8. 戻り値:
  9. 返されたキーの実際の数

2. キーシーケンス関数set_keygenを設定する

  1. void set_keygen( int  
  2. 関数:
  3. keygen を暗号に設定すると、生成されるランダムなキーシーケンスに影響します。
  4. パラメータ:
  5. キー: キー
  6. 戻り値:
  7. なし

3. 乱数を生成する born_seed

  1. int born_seed( int sync, int  
  2. 関数:
  3. 同期コードとキージェネレータに基づいてランダムキーシードを生成する
  4. パラメータ:
  5. sync: 同期コード
  6. キー: キー
  7. 戻り値:
  8. シード

4. キージェネレータをリセットする reset_keygen()

  1. void リセットキー生成()
  2. 関数:
  3. キージェネレータをリセットすると、生成された乱数シーケンスに影響します。

3. テストコードの例

最終的なファイルは次のとおりです。

  1. キー.cキー.h main.c

例1: 生成されたランダムシーケンスの検出

  1. int main( int argc, char *argv[])
  2. {
  3. 整数i;
  4. 符号なし整数長さ;
  5. 整数j、r、キー番号;
  6. 符号なし整数同期 = 0;
  7. 符号なし文字 キー[MAX_KEY_REQUEST];
  8.  
  9.  
  10. キー番号 = 10;
  11.  
  12. printf( "\n--------------デフォルトのキー生成同期コード = 0 を使用して暗号文を生成します----------------\n" );
  13. リセットキー生成();
  14.  
  15. memset(キー,0, sizeof(キー));
  16. len = request_key(sync,key_num, key );
  17.  
  18. print_array( "キー0-9:" , key ,len);
  19.  
  20. memset(キー,0, sizeof(キー));
  21. len = request_key(sync,key_num, key );
  22.  
  23. print_array( "キー10-19:" , key ,len);
  24.  
  25. printf( "\n--------------keygen=1234 同期コード=0 を使用して暗号文を生成します----------------\n" );
  26. set_keygen(1234);
  27.  
  28. memset(キー,0, sizeof(キー));
  29. len = request_key(sync,key_num, key );
  30.  
  31. print_array( "キー0-9:" , key ,len);
  32.  
  33. memset(キー,0, sizeof(キー));
  34. len = request_key(sync,key_num, key );
  35.  
  36. print_array( "キー10-19:" , key ,len);
  37. }

実行結果:

  1. --------------デフォルトのキー生成同期コード = 0 を使用して暗号文を生成します----------------  
  2. キー0-9: ----[10]  
  3. a5 52 c8 14 5d f7 46 5b 89 42
  4. キー10-19: ----[10]  
  5. 38 69 6f a6 08 d2 69 39 cd 29
  6.  
  7. --------------暗号文を生成するには、keygen=1234 sync code=0 を使用します----------------  
  8. キー0-9: ----[10]  
  9. 0e 83 0b 73 ec f5 4b 4a 74 35
  10. キー10-19: ----[10]  
  11. e7 f1 06 41 c8 6b aa df 0c 3d

異なるキージェネレータによって生成されたランダムシーケンスが異なることがわかります。

異なる同期コードを設定すると、シーケンスは異なります。

例2: デフォルトのキージェネレータを使用した暗号化と復号化

  1. 文字データ0[10]={
  2. 0x1、0x2、0x3、0x4、0x5、0x6、0x7、0x8、0x9、0x10、
  3. };
  4. int main( int argc, char *argv[])
  5. {
  6. 整数i;
  7. 符号なし整数長さ;
  8. 整数j、r、キー番号;
  9. 符号なし整数同期 = 0;
  10. 符号なし文字 キー[MAX_KEY_REQUEST];
  11. char buf[120]={0};
  12.  
  13. キー番号 = 10;
  14. printf( "\n--------------デフォルトのキー生成を使用して暗号化を開始します----------------\n" );
  15. リセットキー生成();
  16. print_array( "\nプレーンテキスト:" , data0, key_num);
  17.  
  18. memset(キー,0, sizeof(キー));
  19. len = request_key(sync,key_num, key );
  20.  
  21. print_array( "キー:" ,キー, 長さ);
  22. (i=0;i<len;i++)の場合
  23. {
  24. buf[i] = data0[i]^キー[i];
  25. }
  26. print_array( "\n暗号文:" , buf, len);
  27.   
  28. printf( "\n-------------------- 復号化を開始します--------------------\n" );
  29. リセットキー生成();
  30.  
  31. memset(キー,0, sizeof(キー));
  32. len = request_key(sync,key_num, key );
  33.  
  34.   
  35. (i=0;i<len;i++)の場合
  36. {
  37. buf[i] = buf[i]^キー[i];
  38. }
  39.  
  40. print_array( "\nプレーンテキスト:" , buf, len);
  41. }

テスト結果

  1. --------------暗号化を開始するにはデフォルトのキージェネレータを使用します----------------  
  2.  
  3. プレーンテキスト: ----[10]  
  4. 01 02 03 04 05 06 07 08 09 10
  5. キー: ----[10]  
  6. a5 52 c8 14 5d f7 46 5b 89 42
  7.  
  8. 暗号文: ----[10]  
  9. a4 50 CB 10 58 F1 41 53 80 52
  10.  
  11. --------------------復号化を開始--------------------  
  12.  
  13. プレーンテキスト: ----[10]  
  14. 01 02 03 04 05 06 07 08 09 10

例3 異なるキージェネレータと同期コードを使用した暗号化と復号化

  1. int main( int argc, char *argv[])
  2. {
  3. 整数i;
  4. 符号なし整数長さ;
  5. 整数j、r、キー番号;
  6. 符号なし整数同期 = 0;
  7. 符号なし文字 キー[MAX_KEY_REQUEST];
  8. char buf[120]={0};
  9. 符号なし整数mykeygen;
  10.  
  11.  
  12. (引数が4ではない場合){
  13. fprintf(stderr, "使用法: %s <seed> <key num> <keygen>\n" , argv[0]);
  14. 終了(EXIT_FAILURE);
  15. }
  16.  
  17. 同期 = atoi(argv[1]);
  18. key_num = atoi(argv[2]);
  19. mykeygen = atoi(argv[3]);
  20.  
  21. printf( "\n--------------カスタムキー生成と同期コードを使用して暗号化を開始します----------------\n" );
  22. set_keygen(mykeygen);
  23. print_array( "\nプレーンテキスト:" , data0, key_num);
  24.  
  25. memset(キー,0, sizeof(キー));
  26. len = request_key(sync,key_num, key );
  27. print_array( "キー:" ,キー, 長さ);
  28.  
  29. (i=0;i<len;i++)の場合
  30. {
  31. buf[i] = data0[i]^キー[i];
  32. }
  33. print_array( "\n暗号文:" , buf, len);
  34.   
  35.  
  36. printf( "\n-------------------- 復号化を開始します--------------------\n" );
  37. set_keygen(mykeygen);
  38.  
  39. memset(キー,0, sizeof(キー));
  40. len = request_key(sync,key_num, key );
  41. (i=0;i<len;i++)の場合
  42. {
  43. buf[i] = buf[i]^キー[i];
  44. }
  45. print_array( "\nプレーンテキスト:" , buf, len);
  46. 終了(EXIT_SUCCESS);
  47. }

実行結果は次のとおりです。

  1. --------------暗号化を開始するには、カスタムキージェネレータと同期コードを使用します----------------  
  2.  
  3. プレーンテキスト: ----[10]  
  4. 01 02 03 04 05 06 07 08 09 10
  5. キー: ----[10]  
  6. 53 00 29 cd 27 eb cc 80 1a d7
  7.  
  8. 暗号文: ----[10]  
  9. 52 02 2a c9 22 ed cb 88 13 c7
  10.  
  11. --------------------復号化を開始--------------------  
  12.  
  13. プレーンテキスト: ----[10]  
  14. 01 02 03 04 05 06 07 08 09 10

実際にデータの暗号化と復号化が実現できたことがわかります。

4. データ暗号化の実用化

上記のサンプルコードを使用し、対応する関数を両方の C/S エンドに移植すると仮定します。

完全なデータ暗号化とデータ転送の参照プロセスは次のとおりです。

両者が同じキージェネレータと同期コードを設定する限り、暗号マシンによって吐き出されるキーは同じシーケンスになることを覚えておいてください。

クライアントがメッセージを送信するたびに、独自のプレーンテキスト同期コードがサーバーに送信されます。

サーバーは、事前にクライアントに送信されたキー生成コードと同期コードに基づいて復号化操作を実行できます。

プレーンテキストの同期コードは確認できますが、

ただし、暗号化マシンのアルゴリズムとサーバーから送信されたキー生成暗号文を解読する必要があります。

5. 原則

暗号化アルゴリズムを実装する際の主な問題は、キーとしてランダムなシーケンスを生成する方法です。

この例では、プロトタイプが次のライブラリ関数 rand() を使用します。

  1. #含む
  2.  
  3. 整数rand(void);

rand() 関数はランダムなシーケンスを生成できますが、生成されるシーケンスの順序は実際には毎回同じです。

  1. #include <stdio.h>
  2.  
  3. 主要()
  4. {
  5. 整数i = 0;
  6.  
  7. (i=0;i<10;i++)の場合
  8. {
  9. printf( "%d " ,rand());
  10. }
  11. putchar( '\n' );
  12. }

結果は次のとおりです。

  1. ペン@peng-virtual-machine:/mnt/hgfs/peng/rand/code$ ./a.out   
  2. 1804289383 846930886 1681692777 1714636915 1957747793 424238335 719885386 1649760492 596516649 1189641421
  3. peng@peng-virtual-machine:/mnt/hgfs/peng/rand/code$ ./a.out   
  4. 1804289383 846930886 1681692777 1714636915 1957747793 424238335 719885386 1649760492 596516649 1189641421

毎回異なるランダムシーケンスを生成したい場合はどうすればいいでしょうか?srand()関数を使用する必要があります。

  1. void srand(符号なしintシード);

この関数を通じてシードを設定するだけで、結果のシーケンスは完全に異なります。

通常、time() の戻り値をシードとして使用します。

ここで関数をテストするためのデータをいくつか書きます

  1. #include <stdio.h>
  2.  
  3. 主要()
  4. {
  5. 整数i = 0;
  6.  
  7. srand(111);
  8. (i=0;i<10;i++)の場合
  9. {
  10. printf( "%d " ,rand());
  11. }
  12. putchar( '\n' );
  13. srand(1111);
  14. (i=0;i<10;i++)の場合
  15. {
  16. printf( "%d " ,rand());
  17. }
  18. putchar( '\n' );
  19. }

実行結果は次のとおりです。

  1. ペン@peng-virtual-machine:/mnt/hgfs/peng/rand/code$ ./a.out   
  2. 1629905861 708017477 1225010071 14444113 324837614 2112273117 1166384513 1539134273 1883039818 779189906
  3. 1383711924 882432674 1555165704 1334863495 1474679554 676796645 154721979 534868285 1892754119 100411878

異なるシードを入力すると、異なるシーケンスが生成されることがわかります。

関数のプロトタイプは次のとおりです。

この例の原理は比較的単純であり、複雑なアプリケーション (多方向キー管理など) やデータ セキュリティは考慮されていません。

暗号化と復号化のプロセスのみを説明します。これは、暗号化と復号化のプロセスを学習して理解するためにのみ使用されます。この暗号化アルゴリズムは対称暗号化に属し、比較的単純で解読が容易です。

現在、暗号化および復号化機能は、市場で専門の企業やチームによって実装されています。

この記事はWeChat公式アカウント「Yikou Linux」から転載したものです。下のQRコードからフォローできます。この記事を転載する場合は、Yikou Linux パブリックアカウントにご連絡ください。

<<:  人工知能と教育の統合が高等教育改革を促進

>>:  笑顔は73年にわたる:ディープフェイクがイスラエル建国戦争の古い写真を「復活」させる

ブログ    

推薦する

ML アルゴリズムが製造業に及ぼす影響

製造業の企業は顧客に最高の製品とサービスを提供することを目指しており、最終的な目標は顧客を満足させ、...

...

あなたの顔、5セント

1 「急に悲しくなりました。私のハンサムな顔の価値はたったの50セントだったんです!」昨日、あるニュ...

AIと機械学習が建設業界にもたらす変化

建設業界は長い間、伝統的な手作業のプロセスで知られてきましたが、テクノロジーの進歩により急速に変化し...

変革管理における生成AIの課題

AI が社会に重大なリスクをもたらすという警告が見出しで報じられているにもかかわらず、ボストン コン...

シリコンバレーの人工知能専門家:人類は20年以内に老化の束縛から解放されるかもしれない

現在、世界最高齢の人は、ギネス世界記録に認定された118歳の日本人老人、田中カネさんです。田中選手の...

すべてのAI公開コースが無料でご利用いただけます! 14 のカテゴリ、230 のコース、6,000 以上の GitHub スター

十分に読書をして直感を養い、直感を信じて挑戦してみましょう。たくさんの読書を通して直感を養い、自分の...

AIが生産性と賃金に与える影響

人工知能は、日常的なタスクを自動化することで生産性を向上させる機会を提供します。この記事では、人工知...

MIT の新しい研究: 労働者は AI によって排除されることを心配する必要はありません。コストは非常に高く、視覚的な作業の23%しか置き換えられない

人工知能は私たちの仕事を奪うのでしょうか?シリコンバレーの幹部が今日の最先端の AI テクノロジーに...

...

MITが家中に設置できる紙のように薄いスピーカーを開発

MITのエンジニアたちは、あらゆる表面を音源に変えることができる紙のように薄いスピーカーを開発した...

米メディア記事:米中AI競争は東南アジアにとって何を意味するのか?

2月7日、アメリカの外交政策ウェブサイトは「米中人工知能競争は東南アジアにとって何を意味するのか?...

10社にインタビュー、機械学習のインタビュー内容をまとめました

[[226434]]まずは自己紹介をさせてください。私は機械学習の経験が4年以上あり、主な業務内容と...

AIを活用した臨床モニタリングシステムの台頭

人工知能(AI)は生活のあらゆる分野に浸透しています。人工知能は医療にどのようなメリットをもたらすの...

LeCun 氏はリツイートしました: 中国がトップ AI カンファレンスのリストで首位を占め、米国が 2 位です!中国と米国が世界の数学計算分野を支配している

最近、「科学は戦略だ」というネットユーザーが、近年いくつかの海外の主要メディアや調査機関がまとめたグ...