暗号化と復号のテクニックを解明しようパート2(Deciphering the Technique of Encryption and Decryption Part II)
本日はヴィジュネール暗号(The Vigenère Cipher)にしましょう。
ヴィジェネール暗号
ヴィジェネール暗号は、単純な多表式代替の形を使ってアルファベットのテキストを暗号化する方法です。これは16世紀にBlaise de Vigenèreによって開発され、シンプルなシーザー暗号の改良版です。ヴィジェネール暗号の動作方法は以下の通りです。
鍵:ヴィジェネール暗号はメッセージの暗号化と復号化にキーワードまたはフレーズを使用します。通常、鍵は数字や特殊文字を含まない、文字のみで構成された単語または短いフレーズです。この鍵はメッセージの長さに合わせるために繰り返しまたは拡張されます。
アルファベット:ヴィジェネール暗号は標準の英語アルファベット(A-Z)で動作し、大文字と小文字を区別しません。数字や記号などの非アルファベット文字は通常、暗号文で無視されるか保持されます。
暗号化:平文の各文字は、鍵の対応する文字によってシフトされます。たとえば、鍵の文字が 'A' の場合、シフトは発生しません。鍵の文字が 'B' の場合、平文の文字は1つ前にシフトされます。 シフトを実行するために、通常はモジュラ演算(通常はモジュロ26)を使用してアルファベットを巡回させます。つまり、シフトが 'Z' を超えた場合、 'A' に戻ります。
復号化:メッセージを復号するには、受信者は同じ鍵ワードと逆のシフト(暗号文の文字から鍵の文字を引く)を使用して元の平文を復元します。
Vigenèreスクエアは、Vigenère暗号で暗号化および復号化プロセスを実行するために使用されるアルファベットの表形式の配置です。このスクエアは、テキストを暗号化または復号化する際に適用するシフト値(鍵文字)を特定するのに役立ちます。
Vigenèreスクエアの作成方法:
行:スクエアには26の行があり、各行が英語アルファベットの文字を表し、AからZまでです。
列:列もAからZまでの文字でラベルが付けられていますが、右に進むにつれてアルファベットが繰り返されるサイクリックなパターンで配置されています。このサイクリックな配置はVigenèreスクエアの主要な特徴です。
Vigenèreスクエアを使用して暗号化する方法:
キーワードの選択:暗号化したいメッセージの長さと同じかそれ以上の長さのキーワードを選択します。
キーワードの繰り返し:キーワードをメッセージの長さに合わせるために繰り返します。
交差点の特定:平文の各文字を暗号化するために、Vigenèreスクエアの上部行からキーワードの文字を見つけます。
対応する列の検索:行内のキーワード文字から右に移動して、平文で暗号化したい文字を見つけます。
暗号文の文字:行と列の交差点にある文字が、暗号文の文字です。
Vigenèreスクエアを使用して復号化する方法:
同じキーワードを選択します:暗号化に使用したキーワードを知る必要があります。
キーワードの繰り返し:キーワードを暗号文の長さに合わせるために繰り返します。
交差点の特定:暗号文の各文字に対応するキーワードの文字を、Vigenèreスクエアの上部行から見つけます。
列の検索:行内のキーワード文字から右に移動して、列内で復号化したい文字を見つけます。
平文の文字:行と列の交差点にある文字が、平文の文字です。
VigenèreスクエアはVigenère暗号の理解に不可欠なツールであり、多くの暗号学関連の記事やチュートリアルで、読者がこの暗号の仕組みを理解するのに役立つことがあります。
Vigenère暗号が「HELLO」という平文と「KEY」という鍵を使用する方法は以下の通りです。
平文: HELLO
鍵: KEY
鍵の繰り返し: 鍵を平文と同じ長さにするために繰り返します:
平文:HELLO
鍵:KEYKE
各文字の暗号化: Vigenèreスクエアを使用して、各平文と鍵の文字の組に対する暗号化文字を見つけます。
H(平文) + K(鍵) = R
E(平文) + E(鍵) = I
L(平文) + Y(鍵) = J
L(平文) + K(鍵) = V
O(平文) + E(鍵) = S
最終的な暗号化テキスト: 結果の暗号化テキストは「RIJVS」です。
鍵「KEY」を使用すると、平文「HELLO」はVigenère暗号を使用して「RIJVS」として暗号化されます。鍵は平文の各文字のシフト値を決定します。
それではVigenère暗号を理解したと思います。Vigenère暗号を使用して簡単なC++プログラムを作成して見ましょう。
#include <iostream>
#include <string>
using namespace std;
// Vigenere暗号の暗号化関数
string encryptVigenere(const string &plaintext, const string &key)
{
string encryptedText = "";
for (size_t i = 0; i < plaintext.length(); i++)
{
char plainChar = plaintext[i]; // 平文の文字
char keyChar = key[i % key.length()]; // 繰り返しキーの文字
char encryptedChar; // 暗号化された文字
if (isalpha(plainChar))
{
char base = islower(plainChar) ? 'a' : 'A';
encryptedChar = ((plainChar + keyChar) % 26) + base; // 暗号化
}
else
{
encryptedChar = plainChar; // 非アルファベット文字は変更されずに残ります
}
encryptedText += encryptedChar;
}
return encryptedText;
}
// Vigenere暗号の復号化関数
string decryptVigenere(const string &ciphertext, const string &key)
{
string decryptedText = "";
for (size_t i = 0; i < ciphertext.length(); i++)
{
char cipherChar = ciphertext[i]; // 暗号文の文字
char keyChar = key[i % key.length()]; // 繰り返しキーの文字
char decryptedChar; // 復号化された文字
if (isalpha(cipherChar))
{
char base = islower(cipherChar) ? 'a' : 'A';
decryptedChar = ((cipherChar - keyChar + 26) % 26) + base; // 復号化
}
else
{
decryptedChar = cipherChar; // 非アルファベット文字は変更されずに残ります
}
decryptedText += decryptedChar;
}
return decryptedText;
}
int main()
{
char eOrd;
string plaintext, key, ciphertext;
cout << "暗号化する場合は 'e' または 'E' を、復号化する場合は 'd' または 'D' を入力してください:";
cin >> eOrd;
if (eOrd == 'e' || eOrd == 'E')
{
cout << "平文を入力してください:";
cin >> plaintext;
cout << "キーを入力してください:";
cin >> key;
string encryptedText = encryptVigenere(plaintext, key);
cout << "暗号化されたテキスト:" << encryptedText << endl;
}
else if (eOrd == 'd' || eOrd == 'D')
{
cout << "暗号文を入力してください:";
cin >> ciphertext;
cout << "キーを入力してください:";
cin >> key;
string decryptedText = decryptVigenere(ciphertext, key);
cout << "復号化されたテキスト:" << decryptedText << endl;
}
else
{
cout << "無効な入力です";
}
return 0;
}
説明 :
このプログラムは、Vigenère暗号を使用した暗号化および復号化を実装しています。ユーザーの入力に基づいて、メッセージの暗号化または復号化を選択できます。ユーザーが暗号化を選択する場合、平文メッセージとキーを提供し、プログラムはVigenère暗号を使用して暗号化されたテキストを生成します。復号の場合、ユーザーは暗号文とキーを提供し、プログラムはメッセージを復号化します。Vigenère暗号は繰り返しキーを使用し、プログラムはシフトを実行するためにモジュラ演算を使用します。暗号化および復号化の両方で非アルファベット文字は変更されません。
Vigenèreスクエアを使用してプログラムを実行し、暗号化と復号化を試みてみることは面白いでしょう。それでは、今回の記事をここで終了させていただきます。次回の記事では、もっと複雑なヴァーナム暗号(Vernam Cipher)を紹介いたしますので、ぜひお読みいただければ嬉しいです。
エンジニアファーストの会社 株式会社CRE-CO
su_myat_phyu
参考
RaspberryPiFoundation: Introduction to Encryption and Cryptography
https://www.edx.org/learn/computer-programming/raspberry-pi-foundation-introduction-to-encryption-and-cryptography
プログラムの参考
https://www.geeksforgeeks.org/vigenere-cipher/