AES暗号について
AES(Advanced Encryption Standard)は、アメリカのNISTによって募集、採用された共通鍵暗号です。
共通鍵暗号の中でも、ある程度のサイズごとに処理をするブロック暗号に属しています。AES暗号の1ブロックの単位は128 bitsとなっています(CTRモードの場合、ストリーム暗号のように任意の長さを暗号化させることも可能ではありますが)。
このアルゴリズムは公開されており、暗号アルゴリズムとして多く利用されています。
広く普及したおかげで、インテル系の CPU にも AES-NI という x86 命令セットへ拡張機能として追加されています。
こちらを用いることで、AESの暗号化・復号化をCPUレベルで高速にできるようになっています。
自分でAES-NIを用いて開発する場合は、cpuidでAES-NIに対応しているかチェックした上でAES-NIを用いる必要があるのと、AES-NIに対応していない場合の処理(別の方法でAES暗号を実装しておいてそちらを利用する、制限事項としてエラーとする等)を考慮する必要があります(cpuidの参考 eax=0x01)。
NISTが公開しているドキュメントは以下になります。
FIPS 197 Advanced Encryption Standard (AES)
https://csrc.nist.gov/publications/detail/fips/197/final
Announcing the ADVANCED ENCRYPTION STANDARD (AES)
https://csrc.nist.gov/csrc/media/publications/fips/197/final/documents/fips-197.pdf
・・・うん、ごめん、私は全然読めないw
根拠としてはここだよ、ということで。これを完全に理解しなければならない日が来ないことを祈ろう・・・。
プログラミングするにあたって、「AES暗号は強度十分な暗号なので、コーディングで関数呼び出してちゃんと実装できればそれでいい」という考え方もありそうですが、初期化パラメータの意味などはちゃんと理解しておくべきなので、AES暗号に詳しくない人は、色々な資料をざっくりと読んで理解しておくことをおススメします。そうしないと、暗号プログラムを書く上で脆弱な実装にしてしまう可能性があります。ファイルを暗号化する「ランサムウェア」も、暗号化の実装が割と雑ですよ?
AES暗号のモード
AES暗号にはモードがあり、以下の5つが定義されています。
- CBC(Cipher Block Chaining)
- CFB(Cipher FeedBack)
- ECB(Electronic CodeBook)
- OFB(Output FeedBack)
- CTR(Counter)
モードの違いを簡単に言うと、暗号化のための計算式は同じだが、初期化パラメータがあったり、次のブロックを暗号化する際に直前に暗号化されたデータをフィードバックするといった方法に差があります。
その仕組み上、ECBモードは非推奨とされています。
CryptAPIを使う場合は、どのモードを使うか指定する必要があります。もちろん、暗号化したモードと同じモードでないと復号化できません。
以下のWiki、Cryptrecのページに詳しく書かれています。
暗号利用モード
https://ja.wikipedia.org/wiki/%E6%9A%97%E5%8F%B7%E5%88%A9%E7%94%A8%E3%83%A2%E3%83%BC%E3%83%89
2008 年度版リストガイド (秘匿の暗号利用モード)
https://www.cryptrec.go.jp/report/cryptrec-tr-2004-2008.pdf
AES暗号の鍵長
AES暗号では、、以下の3つの鍵長が定義されています。
また、鍵長によってアルゴリズムの変換の計算回数(ラウンド)が決定されます。
- 128 bits(10ラウンド)
- 192 bits(12ラウンド)
- 256 bits(14ラウンド)
ラウンド回数は、CryptAPIを使う場合は関数内でやってくれているので気にする必要は特にはないです。
AES-NI CPU命令を用いて自力で実装される酔狂な方は、この回数をちゃんとループしないと、他のシステムで暗号化・復号化する場合に互換性が保てないので注意してください。
初期化ベクトル
同じデータで同じ暗号鍵でも、暗号化データを変えるための仕組みです。
暗号化モード別での動作から、CBC、CFB、OFBのモードで設定することになります。
CTRも初期値としてナンスが必要になります。
厳密な意味としては異なるようですが、推測を困難にさせる目的を達成するための初期値という実質的な意味では同じかな、と思います。
(暗号屋さんには怒られそうな感想ですが・・・。)
どのような値にすればいいかなど、先に挙げた「2008 年度版リストガイド」に詳しく述べられているので、参考にするとよいでしょう。
とりあえず、調べて分かった情報をメモしておきました。
新たに分かりやすい資料などを見つけたら、折を見て追記していこうかと思います。