【暗号化】ブロック暗号のモードまとめ (比較表付き)

※「暗号技術入門　第３版」のブロック暗号アルゴリズムのモードについてまとめてみます。間違っていましたら、ご指摘いただけると助かります。


##ブロック暗号とストリーム暗号について
まず、暗号アルゴリズムは主に、ブロック暗号とストリーム暗号があります。

###「ブロック暗号」
ブロック暗号とは、ある特定のビット数のまとまりを一度に処理する暗号アルゴリズムの総称です。

（例）
DESは64ビットの平文をまとめて暗号化し、64ビットの暗号文を作ります。AESは128ビットの平文をまとめて暗号化し、128ビットの暗号文を作ります。

内部状態：保持しない。ブロック単位で処理が完了するので、どこまで暗号化を行ったか覚えておく必要が無い。

###「ストリーム暗号」
ストリーム暗号とは、データの流れ（ストリーム）を順次処理していく暗号アルゴリズムの総称です。

（例）
1ビット、8ビット、32ビットなどの単位で暗号化や復号化が行われます。

内部状態：保持する。データの流れを順次処理していくので、どこまで暗号化したか覚えておく必要がある。

##モードとは
モードとはなにか。
ブロック暗号アルゴリズムを使用し、長い平文を暗号化する際はブロック暗号アルゴリズムを繰り返し使って、暗号化する必要があります。この繰り返しの方法のことを、ブロック暗号のモードと呼びます。

##ブロック暗号の主なモード
- ECBモード：Electronic CodeBook mode   (電子符号表モード)
- CBCモード：Cipher Block Chaining mode (暗号ブロック連鎖モード)
- CFBモード：Cipher-FeedBack mode       (暗号フィードバックモード)
- OFBモード：Output-FeedBack mode       (出力フィードバックモード)
- CTRモード：CounTeR mode               (カウンタモード)

##「ECBモード」
ECBモードでは、平文ブロックを暗号化したものが、そのまま暗号文ブロックになります。
最後の平文ブロックがブロック長に満たない場合にはパディングと呼ばれるデータを埋めてあげます。
”平文を暗号化したもの”=暗号文ブロック、となります。

-特徴-
たくさんあるモードの中で最もシンプルなものです。しかし、ECBモードは最も機密性の低いモードです。
ECBモードでは、平文ブロックと暗号文ブロックは一対一の関係になります。したがって、平文の中に同じ値をもつ平文ブロックが複数存在したら、それらの平文ブロックはすべて同じ値の暗号文ブロックに変換されてしまうことになります。暗号文をみるだけで、平文の繰り返しがわかってしまいます。

##「CBCモード」
CBCモードでは、1つ前の暗号文ブロックと平文ブロックのXOR（排他的論理和）をとり、そのXORの値を暗号化を行います。CBCモードも最後の平文ブロックがブロック長に満たない場合にはパディングと呼ばれるデータを埋めてあげます。
SSL/TLSではCBCモードが使われています。
”1つ前の暗号文ブロック”と”平文ブロック”のXORで得た値を暗号化したもの=暗号文ブロック、となります。

-特徴-
最初の平文ブロックを暗号化するときには「1つ前の暗号文ブロック」は存在しないので、「1つ前の暗号文ブロック」の代わりのビット列を1ブロック分用意する必要があります。
このビット列のことを「初期化ベクトル(initialization vector)」、または、頭文字をとって「IV」と呼びます。
**※初期化ベクトルは、暗号化のたびに異なるランダムなビット列を使用してください**
また、平文ブロックは、必ず「1つ前の暗号文ブロック」とXORをとってから暗号化されます。なので、もし平文ブロック1と2の値が等しい場合でも、暗号文ブロック1と2の値が等しくなるとは限りません。ECBモードが持つ欠点は、CBCモードにはありません。CBCモードではでは、途中の平分ブロックだけを抜き出して暗号化することはできません。暗号文ブロック3を作りたかったら、少なくとも平文ブロック1、2、3まで揃っていなければなりません。

##「CFBモード」
CFBモードでは、1つ前の暗号文ブロックを暗号アルゴリズムの入力に戻します。フィードバックというのは、ここでは入力へ戻すということを意味します。
”CFBモードで暗号化した1つ前の暗号ブロックを暗号化した値（鍵ストリーム）”と”平文ブロック”のXOR=暗号文ブロック、となります。
※CFBモードで暗号化して得られる値を鍵ストリームという。暗号文ブロックとは異なります。

-特徴-
CBCモードと同様、最初の暗号文ブロックを作り出すときには1つ前の出力が存在しませんので、代わりに「初期化ベクトル」（IV）を使用する必要があります。
**※初期化ベクトルは、暗号化のたびに異なるランダムなビット列を使用してください**
ECBモードやCBCモードでは、平文ブロックは暗号化アルゴリズムによって直接暗号化されますが、CFBモードでは平文ブロックは暗号アルゴリズムによって直接暗号化されているわけではありません。
平文とランダムなビット列（この場合、暗号化された値）のXORが「暗号文ブロック」となります。

##「OFBモード」
OFBモードでは、暗号アルゴリズムの出力を暗号アルゴリズムの入力へフィードバックします。
”1つ前の暗号ブロックを暗号アルゴリズムで暗号化した値（鍵ストリーム）”と”平文ブロック”のXOR=暗号文ブロック、となります。
※OFBモードで暗号化して得られる値を鍵ストリームという。暗号文ブロックとは異なります。

-特徴-
OFBモードでも、CBCモードやCFBモードと同様に「初期化ベクトル」（IV）を使用します。
**※初期化ベクトルは、暗号化のたびに異なるランダムなビット列を使用してください**
OFBモードでは、平文ブロックは暗号アルゴリズムによって直接暗号化されているわけではありません。「平文ブロック」と「暗号アルゴリズムの出力」とXORして、「暗号文ブロック」を作り出しています。OFBモードはこの点でCFBモードに似ています。

-CFBモードとOFBモードの違い-
CFBモードは”CFBモードで暗号化した暗号ブロック”を利用するのに対し、OFBモードでは、”暗号アルゴリズムで暗号化した値”を利用する点が異なります。
CFBモードでは、暗号ブロックを利用するため、はじめの平文ブロックから順番に暗号化していく必要があります。平文ブロック１の暗号化をスキップして、平文ブロック２を先に暗号化することはできません。
OFBモードでは、平文ブロックをは無関係に暗号アルゴリズムを前もってぐるぐる回し、XORするためのビット列（鍵ストリーム）しておくことができます。その鍵ストリームを使用すれば、暗号アルゴリズムを使用する必要はありません。

##「CTRモード」
CTRモードは、１ずつ増加していくカウンタを暗号化して、鍵ストリームを作りだすストリーム暗号です。
”カウンタを暗号化した値（鍵ストリーム）”と”平文ブロック”のXOR=暗号文ブロック、となります。

-カウンタの作り方-
カウンタの初期値は、暗号化のたびに異なる値（ノンス）を元にして作ります。
（例）ブロック長が128ビット（16バイト）の場合
66 1F 98 CD 37 A3 8B 4B 　00 00 00 00 00 00 00 01
└--------ノンス--------┘ └------ブロック番号------┘
前半の8バイトはノンスで、暗号化のたびに異なる値にしなければなりません。
後半の8バイトはブロック番号で、この部分がカウントアップしていくことになります。

-特徴-
CTRモードの暗号化と復号化は全く同じ構造になるので、プログラムで実装するのがとても簡単です。これは、OFBモードと同じストリーム暗号の特徴です。また、ブロックを任意の順番で暗号化・復号化することができます。暗号化・復号化の際に使う「カウンタ」は、ノンスとブロック番号からすぐに求めることができるからです。

##ブロック暗号のモード比較表
![Screen Shot 2017-04-30 at 20.20.37.png](https://qiita-image-store.s3.amazonaws.com/0/140455/8ee75a4b-4fd1-2357-9a0f-9ffde01891e8.png)