スパコンでも破れない!
高セキュリティ・マイコン・プログラミング
四半世紀の実績!強度128ビットの世界標準共通鍵暗号“AES”とその応用
- 著者・講師:森岡 澄夫(Sumio Morioka)
- 企画・編集:ZEPエンジニアリング株式会社
- 関連製品:[VOD/KIT/data]強度128ビット! AES暗号セキュリティ・プログラミング入門
- 関連製品:[VOD/Pi KIT]カメラ×ラズパイで一緒に!初めての画像処理プログラミング
- 関連製品:[VOD/KIT]Zynqで初めてのFPGA×Linux I/O搭載カスタムSoC製作
- 関連製品:[VOD/KIT]Tiny FPGA実習!高校生から始めるHDLプログラミング
- 関連製品:[VOD/KIT]Xilinx製FPGAで始めるHDL回路設計入門
- 関連製品:[VOD/KIT]一緒に動かそう!Lチカから始めるFPGA開発【基礎編&実践編】
- 関連記事:USBカメラの動画キャプチャ&描画用 Pythonプログラム
- 関連記事:ライブラリ完備!組立式ラズパイI/O増設ボード MCC DAQ HATSファミリ誕生
- 関連記事:FPGA/Zynqで作るカスタム・コンピュータ・チップ
- 関連記事:Lチカ入門!ソフトウェア屋のためのHDL事はじめ
身近なところで大量に使われている暗号処理
インターネットやスマホなど通信のための身近な装置・環境を扱う際には,必ずと言ってよいほどセキュリティへの関わりが出てきます.
パスワード入力や送付ファイルの暗号化といった人間が行うセキュリティ操作だけではなく,裏側にある通信やデータ加工のいろいろなレイヤで,セキュリティを保つための暗号処理が自動で行われています.
暗号とセキュリティは本来区別すべきですが,ここでは割愛します.暗号処理というとスパイ映画などに登場する遠い世界の話に感じられるかもしれませんが,じつは誰もが毎日普通に使っているものです.
情報や通信の分野に関わりのある技術者や研究者であれば,セキュリティの専門家ではなくても,共通鍵暗号や公開鍵暗号という言葉やその概略について1度は耳にしたことがあるでしょう.
安全性の高い世界標準AES
暗号を破ろうとすると1秒に1兆回試しても1000京年かかる
ここでは最も有名な共通鍵暗号のAESを取り上げます.
AESはAdvanced Encryption Standardの略で,2001年にNISTがアメリカの標準として定めたものですが,事実上,世界の標準と言えます(図1).
それ以前はDES(Data Encryption Standard)という暗号が標準だったのですが,これは現在では旧式とみなされています.とはいえ,AESも登場からすでに四半世紀近く経ちますが,破れるような事態は起きていません.
数理的裏付けをもったアルゴリズム設計と,多くの研究者や実社会利用による長年の公開検証(攻撃)がなされているからであり,まだまだ使われ続けるものと思います.
暗号の安全さ(暗号強度)は,直観的には,鍵の値を知らずに暗号文から平文(元のデータ)を復元する作業の難しさのことを指します.
AESの安全性はおもに,鍵値を効率よく推定するヒントが得られないことと,鍵値をしらみつぶしに1つずつ調べていくと天文学的な時間がかかることに依っています.暗号強度の指標として,おもに鍵長が使われるのはこれが理由です.
AESでは鍵長が最短でも128ビットあり,これは鍵の値が$2^{128}=$340282366920938463463374607431768211456とおり存在するということです.1秒間に1兆個の鍵を調べられる極めて速い計算機でも,すべての鍵を試すのに10790283070806014188年(≒1000京年)かかることになります.
しかし,鍵の値を知っていれば,ラズベリー・パイPicoやArduinoといったマイコンでもほぼ一瞬で暗号化や復号化ができます.
暗号化アルゴリズムは公開されている!
非公開・秘密・複雑化は安全じゃない!?
AESのアルゴリズムは一般に公開されており,仕様書は https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.197-upd1.pdfで見ることができます.
鍵と128ビットの平文(または暗号文)が与えられたとき,それを暗号化(または復号化)するものです.セキュリティにあまり馴染みがないと「暗号などセキュリティに関わる処理は,できる限り非公開・秘密にしたほうが安全」という気がするかもしれませんが,それは数十年前に明確に否定されています.
「複雑なデータ加工をたくさんすればするほどわかりにくくなって安全だろう」という考え方をするのも誤りです.
AESのアルゴリズムは,図2のように4種のデータ加工処理(SubBytes, ShiftRows, MixColumns, AddRoundKey)を1セットとし,10回繰り返すだけのものです.
暗号化アルゴリズムは意外にもシンプル!
基本的には,バイトの数値入れ替えやバイト順の変更を行っています.単純すぎるという印象をもつかもしれませんが,平文中の各ビット値がどのように伝搬していくか等が慎重に吟味されており,大丈夫です.
現代の共通鍵暗号はAES以外にもいろいろな物がありますが,作り方の大筋は類似しています.
上記の各データ加工処理は,整数演算や浮動小数点演算ではなく,有限体(ガロア体と言う場合もある)という特殊な数値体系上の演算として定義されています.
したがってAESアルゴリズムを実行するソフトウェアや専用回路を作るときには,その理解がある程度必要になります.しかし,有限体演算の知識は共通鍵暗号だけではなく公開鍵暗号や誤り訂正符号の実装にも利用でき,とても役立つものです.
脆弱性はアルゴリズムではなく実装不備が原因
通信や情報処理のアプリケーションにおいてセキュリティが破れた,という話を時々耳にすることがあります.それはAESなどの暗号化アルゴリズムが破れたという意味ではなく,秘密鍵管理など実装の仕方に問題があったということです.
セキュリティ処理実装の知識は暗号アルゴリズムの知識とはまた別物であり,発生しうる攻撃を軽視したり仕様を曖昧に理解したりしてソフトウェア/ハードウェア製作をすると,脆弱性が生じやすくなります.
とくに,コーディングやデバッグの簡便さを優先して,「この入力を毎回変えるよう指定されているが,固定値でも大丈夫だろう」「真性乱数を使えと指定されているが,M系列(簡単な疑似乱数の典型)で大丈夫だろう」などと仕様を勝手に解釈してしまう事態が起こりやすく,とても危険です.
共通鍵暗号は認証にも使うことができる
ここまではAESの用途を「データを暗号化し,鍵を知らない人には内容がわからないようにすること」であるものとして説明してきましたが,これは正確には秘匿と言います.
先述のとおり,1回のAES実行では128ビットの平文(または暗号文)を処理します.現実にはもっと長い入力を扱う場合がほとんどであり,図3のようにAESを繰り返し適用します.
もっとも単純なECBモードは,平文を128ビットごとに区切ってAESを適用するものですが,もし同じ平文が複数回暗号化されると,平文の具体的な内容までは判明しないものの, 「同じ入力が複数回与えられた」という部分情報が漏洩してしまう欠点があります.
他の方法にはこの欠点がありませんが,暗号文の途中で1か所でもデータ破損が生じるとそれ以降の復号ができなくなる等の違った欠点があり,使い分けをします.
AESの用途は秘匿だけではなく,「データが壊れたり改ざんされたりせず,元と同じ値であるか確認すること」にも使えます.これを認証と言います.
たとえばデータをインターネットからダウンロードする際に,MD5などのハッシュ値が合わせて示されている事があります.受信データのハッシュ値を再計算して同じ値が得られれば壊れていない,という仕掛けですが,そのハッシュ値の計算に共通鍵暗号を使うことができます(図4).
ただし,一般的なハッシュ関数ではなく共通鍵暗号を使うことによって,「秘密鍵を知っている者だけがハッシュ値(正確にはタグと言う)を計算できるので,第3者がハッシュ値をすり替えることができず,改ざんがないことを保証できる」という大きな利点が加わります.そこで一般的なハッシュとは区別し,メッセージ認証コード(MAC)と呼ばれています.
共通鍵暗号を応用して,秘匿(暗号化)と認証(タグの計算)をまとめて行えるようにした認証付き暗号と呼ばれるものが良く知られています.有名なものとして,AESをベースとしたAES-GCMがあり,ネットワーク通信で多用されているSSL/TLSに採用されています.