暗号理論入門 4.8.1
- 作者: 林芳樹
- 出版社/メーカー: 丸善出版
- 発売日: 2012/04/20
- メディア: 単行本
- この商品を含むブログを見る
4.8 ブロック暗号のモード
4.8.1 ECBモード(electronic codebook mode)
アルファベットが でブロック長が であるブロック暗号を考える。
鍵空間を とし、 に対して、暗号化関数を とし復号化関数を とする。
ECBモードでは任意の長さの平文は長さ のブロックに分けられている。鍵 の適用により長さ の各ブロックは関数 により暗号化される。復号化は に対応する鍵をもつ復号化関数 を適用する。
C++で書いてみる。byteごとの置換で、ブロック長は4byte、鍵は にした。
#include <iostream> class ECB { public: ECB(int* key, const int block_len) : BLOCK_LEN(block_len) { mKey = new int[BLOCK_LEN]; for (int i = 0; i < BLOCK_LEN; ++i) { mKey[i] = key[i]; } } ~ECB() { delete[] mKey; } std::string Encrypt(std::string& t) { // padding last block. int remain = t.size() % BLOCK_LEN; for (int i = 0; i < BLOCK_LEN - remain; ++i) { t += ' '; } std::string e = t; int block_num = e.size() / BLOCK_LEN; for (int i = 0; i < block_num; ++i) { for (int c = 0; c < BLOCK_LEN; ++c) { e[mKey[c] + i * BLOCK_LEN] = t[c + i * BLOCK_LEN]; } } return e; } std::string Decrypt(std::string& t) { std::string p = t; int block_num = p.size() / BLOCK_LEN; for (int i = 0; i < block_num; ++i) { for (int c = 0; c < BLOCK_LEN; ++c) { p[c + i * BLOCK_LEN] = t[mKey[c] + i * BLOCK_LEN]; } } return p; } private: const int BLOCK_LEN; int* mKey; }; int main(void) { int key[4] = {1, 3, 0, 2}; ECB* ecb = new ECB(key, 4); std::string p = "Hello World! block cipher ECB mode."; std::cout << "p : " << p << std::endl; std::string e = ecb->Encrypt(p); std::cout << "enc : " << e << std::endl; p = ecb->Decrypt(e); std::cout << "dec : " << p << std::endl; delete ecb; return 0; }
実行結果
$ ./ecb p : Hello World! block cipher ECB mode. enc : lHleWoo dr!ll ob cckhiepErC mBo .d e dec : Hello World! block cipher ECB mode.
(char単位の置換だから平文が丸見えだ…次はbit単位でやってみるか)
ECBモードは、同一の平文ブロックは同一の暗号文ブロックに暗号化されるため、平文の規則性が暗号文の規則性となって現れる。
攻撃者は同じ鍵で暗号化された暗号文を書き込むことで、情報を書き換えることができる。また、暗号文ブロックの順序も変えることができる。そのため、ECBモードは長い文書の暗号に向かない。