[-]=======================================================================[-]
Wizard Bible vol.29 (2006,11,7)
[-]=======================================================================[-]
x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x
x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x
---- 第0章:目次 ---
x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x
x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x
○第1章:マニアックJavaプログラミング第五回: 〜 ぬるま湯Java 〜 金床 著
○第2章:mixiにアカウント乗っ取り可能な脆弱性 金床 著
○第3章:Black Hat Japan 2006 レポート 金床 著
○第4章:暗号プログラミング 〜前編〜 Kenji Aiko 著
○第5章:基礎暗号学講座 〜 第4回 〜 IPUSIRON 著
○第6章:基礎暗号学講座 〜 第5回 〜 IPUSIRON 著
○第7章:お知らせ
○第8章:著者プロフィール
x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x
x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x
--- 第1章: マニアックJavaプログラミング第五回: 〜 ぬるま湯Java 〜 ---
著者:金床
x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x
x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x
■0x01.) はじめに
ややあいまいな記憶だが、おそらく2001年ごろ、筆者はメイン言語をJavaへと
切り替えた。それまでは3年ほどC++(Borland C++ Builder 以下BCB)を使って
いた。気が付いてみれば2006年ももう後半であり、5年近くの間殆どJavaだけで過
ごしてきたことになる。この5年間仕事でも趣味でもコードを書き続けてきたが、
そのほとんどすべての成果物がJava製である。
最近になって(筆者の本業である)ウェブアプリ周辺では、Rubyが注目されて
いる。耳にしている人も多いかと思うが、Ruby on Railsというフレームワークが
起爆剤となり、世界中で爆発的にRubyの使用人口が増えているようだ。また、Py
thonやPHPなどもこの5年でずいぶんメジャーになってきたようで、活気がどこか
らともなく伝わってくる。
プログラマには、どのプログラミング言語を使うのかという問題が常につきま
とう。かつてサラリーマン時代にCOBOLで仕事をしたことがあるが、その後Perlを
覚えたときに「これは生産性が20倍は違うぞ」と驚愕したものだ(といっても実
際にはCOBOLとPerlでは守備範囲が違うので、単純に比べるべきではないのだが)。
どのプログラミング言語を選択するかでその後の効率は大きく変わってくる。
かつては「どの言語がいいのか?」という話題を見るたびに「より多くの言語
を自分で使える状態にしておき、何か作るべきものを前にしたときに最適の言語
を選ぶ姿こそが正しい」と思っていたのだが、いつのまにか「これもJava、あれ
もJava、それもJava」になってしまっていた。Javaのぬるま湯に頭までつかって
いるのだ。最近になってだんだん他の言語も覚えてみたいなという欲求が出てき
たのだが、その前になぜこんなにもJavaだけで過ごすようになってしまったのか、
少し考えてみることにした。
■0x02.) C++との出会い
1998年頃はとにかくWindows上でネイティブで動作するアプリケーションを作り
たかったので、BCBを選択した。というか実は最初にVisual C++を買ったのだが、
意味がわからずアプリケーションを作れなかったのである。いわゆる挫折である。
プログラミングのプの字もわからなかった頃だったので、いきなりVisual C++は
難しかった(…今さわっても理解できないような気もするが)。
BCBはやさしかった。難易度だけでなく、プログラマに対してやさしい開発環境
だった。何もしなくても矢印のボタンをクリックするだけでウィンドウプログラ
ムが起動するのだ。Visual C++で挫折した後だったのでこのやさしさは筆者の心
をわしづかみにし、アンチマイクロソフトの旗印を鮮明にすることとなった。
その後まったく意味を理解しないまま(いわゆるコピペプログラミングで)何
故かアプリケーションを作り続けることができ、おそらく数万行ほどは「意味は
わからないが目的の動作をしている」ソースコードを書き続けた。今考えると、
この段階ではBCBが用意してくれるVCLというクラスライブラリをただ使っている
状態だった。
転機が訪れたのは書店で「C++ FAQ」という本を購入したときだ。この時点では
もうかなりのボリュームのソースコードを書いた経験があり、またVCLについては
かなり使いこなせていた(と思っていた)ので、「オレはC++は結構できるぜ」と
すさまじい勘違いをしていたのである。しかしこの本を読んでも一体何が書いて
あるのかさっぱり理解できなかった。答えではなく、質問の意味もわからなかっ
たのである。「デストラクタって何だ?」というようなレベルであった。つまり
その時点ではC++という言語は殆ど何も理解できておらず、ただ使いやすく設計さ
れていたVCLを使ってちょこちょこ作業ができる程度のレベルだったのだ。
「C++ FAQ」を読み進めるうちに自分が作ったプログラムが(主にメモリリーク
系の)欠陥だらけ、問題だらけであることがわかってしまい、「今まで作ってい
たのは何だったんだ」という強い脱力感にさいなまされた。しかし何とか頑張っ
てその時点ではじめて「言語としての」C++を勉強しはじめ、他の書籍も片っ端か
ら読み漁り、徐々にまともなC++プログラマへと進歩していった。
余談だが筆者はこのようにいきなりBCBからプログラミングを覚えたので、C言
語の経験は殆どない。malloc関数を使ったことがない、と言えばどの程度のレベ
ルか分かってもらえるだろう。
■0x03.) Javaとの出会い
C++は間違いなく「最強の」そして「最狂の」プログラミング言語である。オブ
ジェクト指向的に使うことで規模の大きいアプリケーションも作れるのに、イン
ラインアセンブラでCPUレベルでのプログラミングも可能であり、またテンプレー
トを使いこなせば想像を絶する高度なプログラミングが可能となる(ちなみに筆
者はテンプレートについてはSTLを使う程度のレベルまでしか理解できなかった)。
そして実行速度も速く、多くのプラットフォームでサポートされている。
しかし欠点も多い。まず何と言っても「落とし穴」が多すぎる。普通にのんき
にプログラミングしていると、かならず足をずっぽり取られてしまうのだ。C++で
罠を避けるためには常に頭の中で「この場合はアレに気をつけないといけない…」
「こういうケースではコレはタブーで…」と最大限の注意を払わねばならないの
だ。これは非常に疲れる。
また、クロスプラットフォームのコードを書くのことが実質不可能である。こ
れは同時にインターネット上で参考になりそうな、あるいは利用できそうなソー
スコードを見つけても、手元の環境ではコンパイルできず動かない、というケー
スが多いことも意味する。BCB時代にはさんざんこれで泣かされた。高いスキルが
あれば移植できることもあるのだろうが、当時の筆者には難しい話であった。
さらにセキュリティの問題がある。バッファオーバーフローやフォーマットス
トリングバグなど、コンピュータを乗っ取ることのできる致命的なセキュリティ
ホールを作る可能性が高い。
そんなC++との激しい戦いで消耗しつつあった筆者の前に、Javaが姿を現した。
■0x04.) 言語と開発環境
このころ(そして今もだが)、筆者にとってはプログラミングはそれ自体が目
的ではなく、ソフトウェアを完成させることが目的となっていた。そのため言語
仕様だけでなく、どのようなクラスライブラリが使用できるのかという点が非常
に重要になっていた。
Javaに手を出して最初の印象は「クラスライブラリが信じられないほど充実し
ている」というものだ。VCLも悪くないライブラリだったのだが、筆者が特に作り
たかったネットワーク関係(ソケット関係)のライブラリはイマイチだった(そ
のためかなり苦労して自作した)。
しかしJavaは違った。最初から完璧な形でソケット関連のライブラリが用意さ
れていたのである。これには感動した。そしてこのクラスライブラリが「標準」
であり、多くのプラットフォームで同じコードが稼働することに驚いた。
言語としてのJavaも筆者を魅了した。C++にあったようなたくさんの落とし穴は
殆ど見あたらず、気軽なプログラミングが可能となっていた。C++で感じていた
「う〜ん、これはちょっと問題なんじゃないのか」という点がことごとく解決さ
れていたのである。「C++の反省をふまえて開発された」という点が筆者のニーズ
とぴたりと一致した。
しかし開発環境はいまいちだった。BCBでプログラミングを覚えた筆者にとって、
統合開発環境(IDE)はあって当たり前のものだ。Javaを勉強する際はjavacなど
を使うコマンドラインでのプログラミングからはじめたものの、javacの起動はあ
まりにも重く、「Javaは重い」というイメージを増幅することとなった。
同じくBorlandから出ていたBorland JBuilderを使ってみたものの、Swingで作
られたIDEはあまりにも重く、またネイティブGUIとのルック&フィールの違いは違
和感が大きすぎた。
そこで出会ったのがEclipseである。
■0x05.) Eclipse
Eclipseで最初に驚いたのはコンパイルがあっという間に終わることだ。BCBで
はコンパイルというのは数分、時には10分かかるものだったのだが、Eclipseでは
エディタ上で変更点を保存するとほぼその瞬間に終わるのである。「Javaは重い」
という常識が覆された。
また、ネイティブGUIで動作するので使っていて気持ちがいい。エディタにviを
使えないという点は残念なのだが、それを補ってあまりある魅力に溢れている。
Eclipseを使い始めたことで、「言語と開発環境は一体だ」と再認識した。
筆者が考えるJavaの魅力は、Eclipseあってのものだ。エディタで編集中にリア
ルタイムでコンパイルが走り、エラーとなる箇所に赤線が入る。保存を行えばほ
ぼその瞬間にコンパイルは完了しているので、すぐに実行し動作を確認すること
ができる。つまりコンパイル型言語とインタプリタ型言語のおいしいところを両
取りしているのだ。
いわゆる「コンパイル型言語」では変更するたびにコンパイルする時間が必要
となるので、その間にプログラマの思考が中断されてしまうと言われる。そのた
め「インタプリタ型言語」は保存して即実行できるから思考が中断されず、多く
のプログラマに支持されているのだ。しかし「インタプリタ型言語」は実行する
まで文法エラーがあるかどうかわからないという欠点を持つ。特に筆者のように
センスがないプログラマは何度実行してもエラー、エラー、エラーとなってしま
い、そのたびに「何行目でエラーだ?」とエラーメッセージを読み解いてエディ
タに戻って…という作業を繰り返すはめになる。
しかしEclipseならば編集中に文法エラーを発見でき、思考を中断されずに即実
行できる。これはあまり大きな声で語られていないが、Java+Eclipseという組み
合わせを決定的に魅力的なものにしている最大の要因ではないだろうか。
他にも関数の名前を変更したいときなどに使えるリファクタリングの機能やク
ラス間の継承関係を把握できる機能など、今や筆者にとっては「必須」となって
しまった機能がEclipseには満載されている。筆者にとって「Java」とは同時に
「Eclipseでの開発」を意味するものとなっている。
■0x06.) 言語仕様
しかしJavaの言語仕様はとても「おかたい」もので、自由度は低い。たまにJa
vaScriptなどを触るとそのあまりの柔軟さに関心させられる。例えば実行時に関
数の中身を書き換えてしまう機能などは非常に魅力的でありJavaでこれが使えた
らな、と強く思う機能のひとつだ(Javassistを使えば似たようなことはできるが、
それでも自由度は低い)。
しかし筆者は「生粋のプログラマ」ではなくどちらかというと「雑草ソフトウ
ェア開発者」という感じなので、プログラミング言語の言語仕様に対するニーズ
はそれほど高くない。Rubyなどを使っているプログラマのメーリングリストなど
でのやりとりを見ていると、そのことを強く感じる。おそらく生粋のプログラマ
にはJavaはとても窮屈な面があるだろう。
■0x07.) GUI
しばらくCUIのプログラミングとウェブアプリケーションの開発ばかりやってい
たのだが、やはりGUIのソフトウェアも作りたい。しかし現状、JavaでのGUI開発
はまだまだ問題がある状態である。BCBで可能だった「マウスでボタンなどの部品
を選び、ぺたぺた貼り付けてGUIを作る」というプログラミングはまだ実現できて
いないのだ。
Javaが標準でサポートしているSwingのようなGUIは、筆者にとっては受け入れ
られないものだ。あの違和感と動作のもったり感は、とうてい使いたくなるもの
ではない。苦労して作ったアプリケーションがあのような使い心地では、満足で
きないのである。
そこで最近はSWTというライブラリを使っている。これはEclipseも使っている、
JavaでネイティブなGUIを使うアプリケーションを作成できるものだ。これはなか
なか悪くない。ただ現状では開発環境が追いついていないため、どうしてもソー
スコード内でボタンのサイズなどの数値を直接入力するスタイルを取らざるをえ
ず、開発効率はとても悪い。Eclipseにプラグインがあるのだが、バグが多く使い
物にならない状態だ。
■0x09.) その他いろいろ
そして筆者はウェブアプリケーション開発で食っている人間なので、やはりサ
ーブレットエンジンのような効率的に開発されたサーバーサイドの仕組みは魅力
的だ。C++などでももちろんウェブアプリケーションを作ることはできるのだが、
かなり効率が悪いと言わざるを得ないだろう。また、RDBMSと連携する箇所も多い
ので、JDBCのように多くのRDBMSをサポートするライブラリが使えるのもありがた
い。これらの要素は言語が広く使われてはじめて実現される側面もあるため、「
シェアが広い」という点が言語自体の魅力になるという考え方もできるだろう。
■0x08.) まとめ
つまり、筆者がプログラミング言語と開発環境に求めるのは次のような点であ
る。
・クラスライブラリが充実しており、また高いクオリティを持つ
・ネットワークプログラミングが可能である(できればSSLもネイティブでサポー
トする)
・エディタの保存と同時にコンパイルが(高速で)終わり、エラー箇所がすぐわ
かる
・関数名の変更などのリファクタリングの機能がある
・オブジェクト指向をサポートしている
・ネイティブGUIのアプリケーションを開発可能である
・クロスプラットフォームである(WindowsとLinuxがサポートされていればとり
あえず満足)
・バッファオーバーフローなどを起こすことができない
・関数の中身を実行時に書き換えることができる
・ウェブ用の効率的なエンジンが存在する
・RDBMSとの相性がいい
このように情報を整理してみると、やはりJavaが頭ひとつ抜き出て魅力的であ
ることがわかる。しかしあまりにもぬるま湯で刺激がないことも確かだ。そこで、
RubyやLispなどの勉強もしてみようかと思っている(Lispの勉強は少しだが開始
した)。RubyについてはEclipse並に充実したIDEが登場することを期待している。
5年後には一体何を使っているだろうか。
x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x
x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x
--- 第2章: mixiにアカウント乗っ取り可能な脆弱性 ---
著者:金床
x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x
x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x
■0x01.) はじめに
2006年10月現在、500万人以上の会員がいると言われるmixi。筆者も楽しく利用
している。今回偶然にもクロスサイトスクリプティングが可能な箇所を見つけた
ので、この脆弱性について報告する。既にmixiには連絡済みであり、該当箇所は
ふさがれている。
■0x02.) 概要
今回発見したのはよくあるクロスサイトスクリプティング脆弱性である。クロ
スサイトスクリプティングは各方面で報告されているとおり、国内・海外を問わ
ず多くのウェブアプリケーションに存在されるとされる脆弱性だ。攻撃者は被害
者のウェブブラウザ上で好きな内容のJavaScriptを動作させることができる。mi
xiのようにセッション管理にCookieを利用している場合、攻撃者はCookieの内容
を盗むことで被害者のアカウントを乗っ取ることができる。
今回見つかった脆弱性では、仕様の違いにより、IEのみでCookieの盗難が可能
である。そのためFireFoxやOpera、Konquerorなどのウェブブラウザではそれほど
深刻な被害は発生しないだろう。
今回の脆弱性は罠のページ内に小さなiframeを設けることなどで被害者が気づ
かないうちにCookieを盗むことが可能なものだ。標的が不特定多数のユーザの場
合、あるいは特定のユーザの場合が考えられるが、どちらのケースでも攻撃者は
罠のページをあらかじめ設置しておき、そこへのリンクを掲示板やメールなどに
埋め込んで標的を誘い出すことになるだろう。
■0x03.) 脆弱性が存在する箇所
脆弱性はhttp://mixi.jp/home.plから呼び出されるhttp://ads.mixi.jp/jserv
er/***(***の部分は任意の文字列)に存在する。例えばURLがhttp://ads.mixi.
jp/jserver/hogeの場合、HTTPレスポンスのボディ部は次のようになる。
-----
document.writeln("");
document.writeln("");
document.close();
-----
内容からわかるとおり、このレスポンスはJavaScriptである。このコンテンツ
は
-----
さらに次のようにすることで、ウェブ上においた(サイズが大きい)JavaScri
ptを実行できる。
-----
http://ads.mixi.jp/jserver/
-----
■0x04.) アカウントの乗っ取り
脆弱性が存在するホストは「ads.mixi.jp」である。つまり、これはmixiでの多
くのアプリケーションが動作するホスト「mixi.jp」とは別のホストである。
mixiではログインする際にCookieが発行されるが、このときdomain属性の指定
はない。FireFoxやOperaではこのようなdomain属性の指定がないCookieは「その
ホストのみ」のものであると認識し、サブドメインを持つホスト(「ads.mixi.j
p」など)にはこのCookieを送出せず、JavaScriptでのアクセスも禁じている。し
かしIEは仕様が異なり、サブドメインを持つホストにもCookieを送出し、JavaSc
riptでもアクセスが可能である。つまり、「ads.mixi.jp」上でdocument.cookie
を読みとると、mixi.jpのCookieの内容にそのままアクセスできてしまうのである。
読みとったCookieを使ってmixiにアクセスすることで、アカウントの乗っ取り
が可能となってしまう。このときパスワードが必要な操作をのぞくすべての機能
が可能となる(ただし、仮にこのようなアクセスが行われた場合、明らかな不正
アクセス法違反であろうと思われる。そのため、もしも読者が別の箇所にクロス
サイトスクリプティング脆弱性を発見した場合でも、このようなアクセスはして
はならない)。
■0x05.) 深刻度は
Cookieに格納したセッションIDでセッション管理を行うウェブアプリケーショ
ンでは、クロスサイトスクリプティングは致命的なものとなる(mixiではセッシ
ョンIDがほぼ固定されているため、さらによくない)。mixiというウェブアプリ
ケーションについて考えたときには、今回の脆弱性は「とても深刻だ」と言える
だろう。
しかし、筆者の私見となるが、mixiというウェブアプリケーションは(単なる)
コミュニケーションのためのものであり、オンラインバンクやショッピングサイ
トのように金やクレジットカードを扱っているわけではない。そのため、mixiと
いうウェブアプリケーション自体が「深刻な」存在ではないのだ。
セッションIDがランダムな文字列でなかったり、最近少し話題になったように
画像に認証がかからなかったりなど、mixiにはセキュリティ方面にそれほどやる
気がないような雰囲気が感じられる。しかし、mixiはあくまで「楽しみ」のため
の存在なので、筆者個人としてはそれで別にかまわないと思っている(例の「イ
ンターネットの現状です」の文句はちょっとどうかと思ったが)。また、ユーザ
数がとても多いことから、セキュリティ面で甘い(力を入れていない)分、パフ
ォーマンスが改善されているという面もあるのかもしれない。セキュリティがカ
チカチでパフォーマンスが遅いよりも、ページがさくさく表示される方がよいと
いうユーザもたくさんいるだろう。
■0x06.) まとめ
今回は偶然みつけたmixiのクロスサイトスクリプティング脆弱性を取り上げた。
筆者はウェブアプリケーションセキュリティに関する話題を扱うメーリングリス
トを運用している。ウェブアプリケーション開発者からセキュリティ関係者まで、
幅広い人々の参加をお待ちしている。ぜひ参加いただきたい。
http://www.freeml.com/ctrl/html/MLInfoForm/seasurfers@freeml.com
x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x
x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x
--- 第3章: Black Hat Japan 2006 レポート ---
著者:金床
x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x
x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x
■0x01.) はじめに
2004年に初開催されたBlack Hat Japan(以下BHJ)は、今年(2006年)も予定
通り10月に開催されることとなった。去年は都合が悪く参加できなかった筆者だ
が、今年は予定を合わせ、参加することができた。参加費用は8万円程度であり、
個人にとっては参加するかどうか迷う金額となっている。筆者は幸いにも会社の
経費にすることができそうだ。
■0x02.) ウェブアプリケーションが中心
今年のプレゼンテーションの内容は「とにかくウェブアプリケーション」とい
った感じで、筆者としてはうれしい流れである。
BHJでは2つの会場で同時にプレゼンテーションが行われるため、どちらを見る
か選ぶ必要がある。しかしほぼ全てのコマでどちらか片方がウェブアプリケーシ
ョンに関するプレゼンテーションだったため、ほとんど迷う必要がなかった
■0x03.) kawa氏と再会
初日の午前中は(BHJ開催者である)ジェフ・モス氏による挨拶と、続いて基調
講演があった。筆者はとりあえず午後からのテクニカルなセッションに焦点を定
めていたので、体力を温存するために午後から参加することにした(通勤電車が
苦手なのが一番大きな理由なのだが)。タイミング悪くやってきた台風のせいで
あいにくの雨だった。
昼過ぎに会場に到着する。今年の会場は新宿の真正面にある京王プラザホテル
である。事前登録を済ませてあったので受付でカードを見せ、手続きを行う。一
昨年のBHJ2004ではプレゼンテーションの資料が全て印刷された冊子をもらうこと
ができたのだが、今年は客足がよかったせいか部数が足りなくなってしまったら
しく、筆者は手に入れることができなかった。冊子があればプレゼンの最中に書
き込みをしておき、後から質問するときに使うことができる。「あなたの分はも
うありません」と言われていきなり面食らったが、冊子にはとても重いというデ
メリットもあるので我慢することにした。「CD-ROMに同じ内容が入っていますか
ら」と言われたが、筆者のノートPCにはCDドライブが付いていない。「しょぼー
ん」と言おうかと思ったがやめておいた。
会場は広く、ゆったりと座れて文句がない。もちろんエアコンも効いている。
どこに座ろうかと見回しているとkawa氏が声をかけてくれた。最前列に陣取って
いたkawa氏のとなりの席に座ることにする。最近イベントや呑み会などに顔を出
していなかったこともあり、kawa氏と会うのはAD2003以来、なんと3年ぶりである。
はじめて知り合ったころに比べ、とてもたくましくなったkawa氏としばらく談笑
する。筆者の名札(本名と、本当の会社の名前・役職が書かれている)を見るな
り「これホントですか〜?」と疑いの目を向けられて苦笑した。次回は「金床」
の名札での参加にチャレンジしようと思う。
kawa氏と最近のインターネット上のセキュリティ情勢について話し合う。どう
やらこの数年で、攻撃のターゲットは大きくウェブアプリケーションに傾いてき
たようだ。その後SOC系の仕事をなさっているI氏にもひさしぶりに会うことがで
きたのだが、彼も同様に「今は攻撃は殆どウェブアプリですよ」と言っていた。
これはとても刺激的な話であった。
■0x04.) AJAXセキュリティ
13:00からアレックス氏による「AJAXウェブアプリケーションへの攻撃: Web2.0
の脆弱性」というプレゼンテーションに参加した。冒頭、アレックス氏が同時通
訳されていることを完全に忘れてマシンガントークを開始したため、「SLOW DOW
N」のサインが出て笑わせてくれた。その後はそこそこゆったりとした速度で話し
てくれたため、筆者の不安な英語力でもなんとか内容を理解することができた。
筆者はAJAXアプリケーションの開発は殆ど経験がないため、セキュリティ面で
も新しい不安要素はあるのだろうと予想はしていたものの、具体的な中身につい
てはあまり知識がなかった。このプレゼンテーションではまさにそのような「AJ
AXアプリケーションになってどんな新しい問題が出るか」を具体的に解説してく
れたため、個人的にとても参考になった。
AJAXアプリケーションではユーザが意識しない(いわば裏側で)やりとりされ
るHTTPセッションが存在する。そのレスポンスは通常JavaScriptで書かれたアプ
リケーションが受け取って内容を解釈し利用するものであり、直接ウェブブラウ
ザがそのレスポンスを解釈することは想定されていない。そこで、罠ページなど
を利用し、ターゲットのウェブブラウザに直接そのような(裏側に当たる)URLに
アクセスさせることでクロスサイトスクリプティングなどの攻撃が行われる可能
性がある。これはなかなか面白い。
また、AJAXアプリケーションでは大量のJavaScriptがはじめにダウンロードさ
れ、続いてその中からユーザの操作に応じて必要な機能(関数)が呼び出される
というパターンが多い。このような場合、攻撃者はそのウェブアプリケーション
がどんな機能を持っているのかを調べるのが(いわゆるWeb1.0のアプリケーショ
ンに比べて)とても簡単になる。
そして、AJAXアプリケーションはJavaScriptによって複雑なやりとりを行うも
のが多くなるため、ウェブアプリケーションの検査は今まで以上に自動化が難し
くなる。これは検査を仕事にしている人にとっては非常に頭の痛い問題であろう。
このプレゼンテーションではCSRFにも触れていた。どうも最近は「CSRF」また
は「XSRF」と書くようだ。また、発音に注目していたのだが、「シーサーフ」と
は読まず、「クロスサイトリクエストフォージェリ」「エックスエサールエフ」
「シーエサールエフ」と読んでいた。
彼がCSRFの説明をする際に「日本ではCSRFは何と呼ばれているのかわからない。
ワンクリックか?」と聴衆に話しかけたところ、一人の(おそらく)日本人が「
そうだ、ワンクリックだ」と答えていた。…いや、それは違うのでは。英語の「
One Click Attack」はたぶんCSRFのことだが、日本語の「ワンクリック」は「ワ
ンクリック詐欺」のことなのではないかと思うのだが。しかし筆者はそのとき「
ワンクリック詐欺」が実際には何なのかよく知らなかったので、強気に訂正する
ことはできなかった。
■0x05.) イントラネットへのJavaScriptによる攻撃
続いてWhiteHat SecurityのCTOであるジェレマイア・グロスマン氏によるプレ
ゼンテーションがはじまった。彼のプレゼンテーションの内容は基本的にはBlac
k Hat USAでのものと同じである。何週間か前から資料がウェブ上で手に入る状態
であり、筆者はその内容には目を通してあった。そのため最初の方は「ああ、知
ってるなぁ…」とやや退屈だったのだが、デモになっていっきに目が覚めた。彼
のデモはかなり周到に用意されており、JavaScriptマルウェアでターゲットのウ
ェブブラウザを遠隔操作する様子を見ることができた。
理屈では「JavaScriptでそこまでできる」ことを知っているつもりだったが、
目の前で実際に動くものを見せられると「…これはすさまじい」とかなりの衝撃
を受けた(と同時に「デモのためにここまで作るとはなんという暇人」とも思っ
たのは内緒である)。
そのマルウェアはウェブサーバーとの間でポーリングで通信をしている。攻撃
者はそのウェブサーバー経由でターゲットのウェブブラウザ上で動作するマルウ
ェアへ命令を送る。命令はJavaScriptで記述されたソースコードそのもので、例
えば「alert('hoge');」という命令を送るとターゲットのウェブブラウザ上でそ
のスクリプトが実行され、「hoge」というダイアログが出現する。
ジェレマイア氏はこの命令を送信する側(遠隔操作するコンソールのようなも
の)もウェブブラウザから操作できるように作っており、プレゼンテーションに
かける意気込みが半端な物ではないことが伝わってきた。ちなみに彼は巨漢の大
男で、壇上を移動するとミシミシときしむ音が会場に響いていた。
彼の英語は筆者には聞き取りやすかった。またはじめからきちんと同時通訳を
意識して間を空けて話をしていた。いかにもプレゼン慣れしている感じである。
このプレゼンテーションでもCSRFが紹介された。そして、対策としてトークン
方式とCAPTCHA方式の2つが紹介されていた。CAPTCHAは確かにCSRF対策になるのだ
が、人間とボットを区別する必要がないのならばわざわざCAPTCHAを採用する必要
はなく、hiddenフィールドを利用するトークン方式で充分である。しかしウェブ
上ではCSRF対策としてCAPTCHAを推奨する記述が多い。CAPTCHAはユーザビリティ
の面で非常に問題があるので、そのあたりについて機会があれば彼と話をしてみ
ようかと思った。また、CSRF対策としては他に「パスワードの再入力を求める」
という方法もある。
このプレゼンテーションの内容はウェブアプリケーションセキュリティに関わ
る人には必見と言える内容であった。
■0x06.) 国際化されたソフトウェアへの攻撃
このプレゼンテーションではまさにわれわれ日本人が直面している、マルチバ
イトキャラクターでのみ発生するセキュリティ上の問題点についての解説が行わ
れた。筆者はこの分野がとても苦手で、ほとんどの内容が初めて見るものであっ
た。コードページ、Unicodeなど色々なキーワードが登場していたが、個人的には
まず基礎から勉強してこないとだめだと再認識させられることとなった。
■0x07.) データハウスへ
その後レセプションが予定されていたのだが、筆者はこれには参加せず、会場
からすぐ近くにあるデータハウスでMaDさんと打ち合わせを行った。その際スパム
メールの教科書を頂いた。役得である。
■0x08.) 2日目
次の日も午後からの参加となった。筆者はふだん引きこもりのプログラマをや
っているため、1日目は社会復帰というか「人がいっぱいいる雰囲気」に慣れるだ
けで精一杯だった。しかし2日目になると少し余裕が生まれ、また1日目でだいぶ
耳が「英語耳」になってきたので、積極的に(とくに外国人に)話しかけること
にした。
■0x09.) Adli
ロビーで誰か話しかけられそうな人物がいないかと見回していると、ちょうど
目の前を通った肌の黒い若者と目があった。ふだん(たとえば町中で)は面識が
ない人間と目があった瞬間に挨拶をするなど考えられない。しかしそのときは誰
にでも話しかける気まんまんだったため、とっさに「ハイ」と口をついて出た。
彼は「HITB」と書かれた黒地のTシャツを着ており、スーツ姿が多い会場内で
(しかも肌が黒い系の人間は2,3人しかいなかったので)かなりいい感じに浮い
ていた。彼は挨拶はしたものの素通りしていなくなってしまったのだが、その後
すぐにロビーに姿を現したので、話しかけてみることにした。
彼の名前はAdli(アドゥリ)。Tシャツに書かれたHITBの文字はマレーシアで行
われるアジア最大(と、うれしそうに自慢していた)のハッカーカンファレンス、
「Hack In The Box」のことだ。彼はHITBの運営スタッフの一員であるらしい。H
ITBは毎年9月頃にマレーシアで開催される。ちなみに彼はマレーシア人だ。日本
は初めてで、今回はBHJ2006に焦点を合わせた、わずか3日たらずの旅程だそうだ。
後で受け取ったメールでわかったことだが、マレーシアのCERT、MyCERTの一員ら
しい。専門は主に侵入検知らしく、おそらくIDSなどを使っているのだろう。
BHJには個人として参加しているのか?それとも会社として?ときかれる。筆者
は会社ではウェブアプリケーション開発、趣味でセキュリティをやっているので、
個人と会社とどっちとも言える。そんなわけで返答に迷いながらそのことを説明
すると、「それは一番いいパターンだよ」と言っていた(ちなみにその後ジェラ
マイア氏も同じことを言っていた)。
ウェブアプリケーションファイアウォール(Guardian@JUMPERZ.NETのこと)を
開発しているんだ、と言うと興味を示してくれた。マレーシアではmod_security
を使う機会があるらしい。しかしmod_securityはApacheでしか動作しないので、
IISでも使えるものも欲しいそうだ。ぜひ試してみてくれと伝える。
アドゥリの英語は筆者にとってとてもわかりやすいタイプだった(インド系の
なまりだろうか)ので、ほとんど問題なく会話することができ非常にうれしかっ
た。英語の話になり、「日本ではSQLのことをエスキューエルって発音するのに、
今日来たらみんなシーキュルって発音するからびっくりしたよ」と話すとウケて
いた。そう、「SQL Injection」は「シーキュル・インジェクション」なのである。
その後開発言語の話(PHPはコンセプトからして駄目だとか)の話などで盛り上
がった。筆者は主にJavaを使って開発していると伝える。
マレーシアからはるばる日本に来てくれたので、何かプレゼントがないかと考
えた。そしてこの日会場のブースで購入してあったハッカージャパンの最新号を
プレゼントすることにした。「日本語は読めないよ」と笑っていたが、「絵とソ
ースコードを楽しんでよ」と言うとうれしそうに受け取ってくれた。お返しにHI
TBのかっこいいステッカーを2個もくれた。このステッカーは今原稿を書いている
ノートPCに貼ってある。
来年もHITBをやるから、ぜひマレーシアに来いと誘われる。HITBで行われたプ
レゼンテーションは資料などがウェブ上で無料で手に入るらしく(筆者は未チェ
ックだったのでこれから見てみようと思っている)、「情報はフリーであるべき
だ」がHITBのコンセプトだと少し格好つけて教えてくれた。また、今年のHITBで
はふたりほど日本人がいたはずだ、と言っていた。おそらくtessy氏とVlad氏では
ないかと思う。ちなみに今年のHITBでのコンテストで優勝したのは韓国のチーム
だったそうだ。
日本には(日本独自の)セキュリティカンファレンスはないのか、ときかれる。
数年前まで「Attack & Defence」というクールなイベントがあったのだが、逮捕
者などを出してしまい、今は無くなってしまったんだ、と伝える。
アドゥリは知的でありながらやさしく誠実な感じで、とにかく好青年という人
物だった。こういう楽しい出会いがあるので、プレゼンテーションの内容などに
よらず、来年のBHJにも参加しようという気になる。英語ももっと勉強しなければ。
■0x0A.) luminさん
2日目の午後からluminさんのプレゼンテーション、「Winnyのプーさん」に参加
する。luminさんは同時通訳の速度を気にしながらきちんとプレゼンテーションを
進める。luminさんはゆっくりと日本語でしゃべっていたので、筆者としてはとて
も余裕があった。そこで「どんな風に英訳されているのだろう?」と思い、イヤ
ホンをつけて英訳の音声をきいてみることにした。
すると信じられないほどの速度でluminさんの言葉が翻訳されていく。後できい
てわかったことだが、やはり事前にある程度の打ち合わせがあるそうだ。それに
しても見事な速度だった。内容に関しては「むむ?」と思うところも少しあった
が、これは技術的に非常につっこんだ話となるところなので、しかたないところ
だろう。Winnyネットワークのアップロード・ダウンロード・キャッシュなどの概
念を理解している人でないと翻訳が難しいところがあった(逆にそんなのを完全
に理解している女性はイヤである)。
英訳は何人かの女性が交代で行っている。イヤホンなので翻訳者の女性がマイ
クに向かって話す声が耳元で聞こえる。luminさんが「キンタマウイルスが…」と
言ったところで筆者は「キンタマはどう訳すのだろう?」とドキドキワクワクし
ていたのだが、あっけなく「Antinny」と訳しており、心の中で「そう来たか」と
激しくツッコミを入れてしまった。事前打ち合わせ恐るべし。
Winnyネットワークを常に監視しているだけあってまた濃い話をきくことができ
た。内容はpdfファイルで確認することができるので、興味のある人は参照すると
よいだろう。
現在ネットエージェント社が行っているような「P2Pネットワークの監視」は、
プロトコルを解析して互換性のある専用のクライアントを作ることで行われる。
(ファイル共有のための)P2Pネットワークが機能するならば、どんな暗号が使用
されていてもクライアント自身はその通信内容を復号できる(そうでなければダ
ウンロードしたファイルを再生することなどができない)。つまり、「ネットワ
ーク監視を防ぐ」ためには暗号化というアプローチは無駄なのである。ただし、
配布元のホストを特定できないようなプロトコルを設計することはできるだろう。
ぼんやりプレゼンテーションを見ながらそのことに気付いた。
■0x0B.) Jeremiah
Jeremiah Grossman(以下ジェレマイア氏)はCross Site Tracingの発見で知ら
れるWhiteHat SecurityのCTOだ。彼はウェブアプリケーションセキュリティの分
野では有名な人物である。ロビーでのんびりしているところを発見したので、話
しかけてみることにした。
ジェレマイア氏はプレゼンテーションの中で、CSRFの対策としてトークン方式
とCAPTCHAをあげていた。前述したとおり、筆者としては「CAPTCHAはボットと人
間を区別するために使用するべきものなので、CSRF対策としてあまり取り上げる
べきではない」という意見があった。しかし情けないことに英語力不足が原因で、
ニュアンスをいまひとつうまく伝えることができなかった。それに、どうやら彼
はあまり細かいことにはこだわっていないようで、「CSRF対策のついでにbot対策
にもなるから一石二鳥」のように思っているようだった。まあ、そういう考えも
あるだろう。
第三の対策として「パスワードを再入力させる」というのもある、と伝えると、
少し考えた後に「確かに対策になるね」とこちらは納得してくれたようだった。
ウェブのセキュリティの現状などについて少し話をし、最後に名刺を交換した。
名刺は会社のものだったのだが、裏に手書きで「Kanatoko http://www.jumperz.
net/」と書いて渡した。するとどうやらjumperz.netを見たことがあるらしく、「
おお、お前がjumperzの管理人なのか」のようなことを言われた。ウェブアプリケ
ーションセキュリティのメーリングリストなどに何回かポストしたことがあった
ので、おそらくそのときに見てくれていたのだろう。知っていてくれたのがうれ
しくて少し舞い上がってしまった。
そういえばアドゥリに名刺を渡すとき(こちらも同様に裏にKanatokoと書いた)
「こっちがビジネスサイド、こっちがプライベートサイドだよ」と言うと、ニヤ
リとしながら「ハッカーサイドだね」と言っていた。
さて筆者は短パンとTシャツという姿(しかもTシャツの肩のあたりにドクロマ
ークがあった)で参加していたのだが、会場は殆どの人がスーツ姿だったため、
かなり浮いていたようだ(AIDOさんにも目立っていたと言われた)。そのためこ
のときジェレマイア氏の脳内に一瞬にして「短パン野郎=Kanatoko」の情報が埋め
込まれたようだ。
なんと帰国後の彼のブログ(http://jeremiahgrossman.blogspot.com/2006/10
/blackhat-japan-2006.html)に「こいつが金床」という説明つきで筆者の写真が
載ってしまっていたのである。写真は筆者がDan Moniz氏のプレゼンテーションの
後に質問をしているところだ。
おそらくジェレマイア氏は当時は適当にあちこち写真を撮っていて、後から「
ああ、この写真に写ってる短パンのドクロTシャツはKanatokoじゃないか」と認識
し、「Dan Moniz answering question from Kanatoko from Jumperz.net」という
コメントを付けたのだろう。発見したときは爆笑した。ちなみにこのエントリで
は外国人の目から見た東京の印象、魅力などがわかってとても楽しい。
■0x0C.) XSSとネイティブコード
続いて参加したのがDan Moniz氏によるXSS関連のプレゼンテーションだ。Dan氏
は「いかにもハッカー」という雰囲気を出している人物だ。プレゼンテーション
の内容はMetasploitプロジェクトなどで有名なHDM氏と共同で作成したものらしい。
今回HDM氏は来日できなかったようで、個人的には少し残念だった。
プレゼンテーションの前半ではMySpaceやYahooで発生したJavaScriptワームの
実例について紹介していた。このあたりはそれほど驚くような内容ではなかった
のだが、後半になってふと画面に映し出されたソースコードを見ると、なんとC言
語である。
XSSが主題なのになぜC言語?まさかHTTPクライアントをCで書く派か?と思って
いると、どうやらWindowsマシンに感染させるマルウェアのプロトタイプのようだ。
「いかに派手な(激しい)ワームを作るか」という面での思考実験らしい。
拡散の速度ではMySpaceのような巨大サイトに存在するXSS(やCSRF)を利用す
るJavaScriptワームが最高なので、それを利用する。その際、IEの脆弱性を利用
し、ネイティブコードの実行ファイルをダウンロードさせてクライアントPCに感
染させる。感染した(ネイティブコードで書かれた)ワームはIEがHTMLのフォー
ムを送信する際のAPIをフックし、ユーザが色々なウェブサイトを訪れ、何かしら
のフォームを実行する度に自動的にXSSの穴を探す。仮に穴があった場合はそこに
JavaScriptマルウェアを埋め込み、さらなる感染を狙う、というもののようだ。
つまり完全に攻撃サイドの思考に基づくもので、あまりにも見事に攻撃のこと
しか考えていないので笑ってしまった。こういう内容のプレゼンテーションもあ
るところがさすがBlack Hatである。日本人にはこんなあぶないプレゼンをやる人
はもういないだろうし、きっと受けも悪いだろう。
プレゼン後にスピーカーテーブル(プレゼンテーションの後、スピーカーに通
訳付きで質問をできる場所)で少し質問し、「すばらしいプレゼンでしたよ」と
言うととてもうれしそうに握手してくれた。
■0x0D.) AV2006
BHJ2006の後はAV2006である(誘ってくれたkawa氏に感謝)。AV2006はびっくり
爺さんやチームチドリをはじめとするDEFCON参加組が始めたらしいイベント(基
本的には呑み会)である。AVはおそらく消えてしまった某イベントにかけている
のだと思われるが、びっくり爺さんが絡んでいることから、「AV」はおそらくア
ンチウイルスの略ではないと思われる。
最初は参加しているメンバーを把握していたのだが、その後どんどん増えてい
ったため、結果的には誰がいたのかすっかりわからなくなってしまった。企業に
てセキュリティ系の仕事をしている人が多数、自らITセキュリティ関連の会社を
興している人、銀行員、ハッカー雑誌の編集者、そして筆者のような引きこもり
などなど、多彩な顔合わせであった。
セキュリティ系のメンツで呑むのはとても久しぶりである。マニアックなネタ
も通じて楽しい呑み会となった。BHもいいが、やはりADのようなイベントが欲し
いよねぇというのは共通する声であった気がする。
ハッカージャパンの編集部の人ともお話することができた。前々号のとある記
事に不満があったのでそれを伝えたのだが、基本的にはライターの人に言ってく
れということであった。また、帰りがけに無料にて最新号を一冊譲っていただい
た。まさに役得である。どうもありがとうございます。
kawa氏の「ゴルゴメソッド」は面白かった。これは、セキュリティ系のサービ
スを提供する際に、クライアントに「どこまでなら守れるのか」という意味で限
界があることを伝える際に使う。
「だって、いくら優秀なボディガードを雇ったって、ゴルゴに狙われたらおし
まいですよね?つまりそういうことです。この○×侵入防止システムは通常のレ
ベルの攻撃は防ぎますが、ゴルゴ級のハッカーを防ぐことはできないです。Gは無
理です。」
こう言えばクライアントも心の底から納得するという。
内輪ネタで申し訳ないのだが、一部の人々の間で筆者は「人間IDS」として知ら
れている。コミュニティ内などで「こいつは何かおかしい」というニオイをかぎ
分ける能力に長けているらしいのだ。今までに二度ほどインシデントを検知した
実績があり、そのネタで盛り上がってしまった。「金床さんは日本のセキュリテ
ィコミュニティを救いましたよ!」とまで言われて爆笑する。また、今年初めに
発生した最新のインシデント(筆者はいち早く異変を察知して抜けたため詳細は
知らなかったが)のネタでも盛り上がってしまった。
筆者が知る限り、日本のセキュリティコミュニティの人々は(セキュリティに
関わっているというのに)対人関係について警戒心がなさすぎるのである。筆者
のように「まず疑う」というスタンスは決しておすすめできるものではないが、
詐欺師を見破るためには必要なことだ。
■0x0E.) まとめ
BHJは一昨年と変わりなく、最新の技術にフォーカスしたイベントで、とても素
晴らしいものだ。また、人々がお互いにコミュニケーションを取りやすいように
配慮されており、積極的に人間関係を広げたい人にはとてもありがたいイベント
なっている。プレゼンテーションの中身自体は当然だが、コミュニケーションを
取るための場としても魅力的なイベントだ。
海外からわざわざ(?)BHJに参加する人たちもたくさんいた。そのことを考え
れば、筆者のように2時間弱で会場にたどり着けることはとても幸運なのかもしれ
ない。
本場のBHやDEFCONと異なり、規模が小さいことも逆に魅力になるようだ。ジェ
レマイア氏はブログで「(海外で開催されるBHは)本場USAのBHよりも小規模なの
で親密さがあるイベントであり、とても楽しい」のようなことを書いている。ま
だ200人程度と小規模であるため、プレゼンテーションの後にスピーカーと充分な
時間会話することもできる。ジェフ・モス氏を捕まえて会話したりすることもで
きるだろう。筆者は来年も参加するつもりである。
x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x
x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x
--- 第4章: 暗号プログラミング 〜前編〜 ---
著者:Kenji Aiko
x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x
x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x
■0x01.) はじめに
インターネットが普及し、様々な情報がやり取りされる現在のネットワーク状
況において、ここ数年、特に注目されている技術に暗号があります。例えば、SS
L(Secure Sockets Layer)はHTTPにて広く使われている暗号通信方式であり、私
たちは普段、URLの先頭が「https」となっているWebサイトをよく見かけます。ま
た、かの有名なP2P(Peer to Peer)ソフトであるWinnyも、Crack対策のため、通
信内容を暗号化して送受信していました。
今後、ネットワークと暗号はますます身近になり、またその研究も進むことで
しょう。しかし、暗号はそもそもコンピュータやネットワークとはまったく別の
学問であり、その歴史も深く、専門の学者によって日々研究が進められているも
のです。暗号に対する安全性や理論の証明、そしてネットワーク通信にどのよう
に応用できるかなど、暗号と一言にいっても様々な分野があり、そのすべてを学
ぶことは困難です。ましてや、プログラマやネットワークエンジニアといったコ
ンピュータ業界の人間が、片手間に学習して身につけることができるような簡単
なものでもありません。
しかし、プログラマは新たな暗号アルゴリズムを発見する必要はなく、あくま
でも実装レベルでの知識を持っていればよいことも事実です。そして、暗号関連
のライブラリも様々なところで作成配布されており、それらを利用して簡単に暗
号を使うことが可能です。よって、今回は、暗号を利用したプログラミング方法
を解説します。このテキストを読み進めていくための、暗号に関する詳細な知識
は必要ありません。
ただ、このテキストは、あくまでもプログラマ向けに記述していますので、純
粋な暗号分野の方から見れば、間違いや説明不測が多々あるかもしれません。し
かし、その辺りはスルーしてもらえると助かります。書いてる私自身も、暗号理
論自体はほとんど理解していない状態なので(^^;。
というわけで、今月と来月の2回に渡って「暗号プログラミング」をお送りした
いと思います。
■0x02.) 暗号の種類
コンピュータ業界でもっとも多く利用されている暗号方式は、大きく分けて2つ
あります。それは「共通鍵暗号」と「公開鍵暗号」です。研究レベルの話だと分
かりませんが、少なくともコンピュータで使用する暗号は、この2つを知っていれ
ば十分です。なので、とりあえずこの2つを覚えてください。
それで、よく暗号関連のテキストを読んでいて「分かりにくいなぁ」と思うの
で、ここでひとつはっきりさせておきます。「共通鍵暗号」は他にも「秘密鍵暗
号」というような呼び方で呼ばれるらしいです。ただし、これらは全部同じで、
要するに、「通信するそれぞれの相手が同じ鍵を持っている暗号方式」というこ
とです。
「公開鍵暗号」は他に呼び方はないと思いますが、間違えやすいのが、公開鍵
暗号の解説の中で「秘密鍵」という単語が出てくるところです。正直まぎらわし
いです。「公開鍵暗号」の中で使用される「秘密鍵」という単語と、「秘密鍵暗
号(共通鍵暗号)」とはまったく別物です。無関係です。とりあえずはこの2点を
押さえておいてください。
ちなみに「公開鍵暗号」とは、暗号化するための鍵と、復号化するための鍵が
違うという、まったくもって意味不明(というか、そんなこと可能なの?)な暗
号化アルゴリズムなので、ちゃんとした知識を持って利用する必要があるようで
す。
では、この2つの暗号方式について、もう少し詳しく見ていくことにします。
■0x03.) 共通鍵暗号
共通鍵暗号とは、通信を行う双方が共通の鍵を利用した暗号方式です。考え方
はとても簡単です。通信するそれぞれの相手が同じ鍵を持っており、それを使っ
て暗号化や復号化を行うわけです。コンピュータの世界では、すべては0と1で表
現されますから、もちろん、平文も暗号文も鍵も0と1の羅列でしかないわけで、
要するに「双方とも同じデータ(鍵)を持っていれば、暗号通信が可能ですよ」
というだけの話です。
+-- client ------------------------------------------------+
| 平文「BBBB」を鍵「aaaa」で暗号化し、相手に送信 |
+----------------------------------------------------------+
↓平文「BBBB」を鍵「aaaa」で暗号化した暗号文「CCCC」
+-- server ------------------------------------------------+
| 暗号文「CCCC」を鍵「aaaa」で復号化し、平文「BBBB」を得る |
+----------------------------------------------------------+
ネットワーク上では、暗号文「CCCC」しか流れないため、鍵「aaaa」が他の人
間に知られない限りは、平文が求められることはありません。仕組みとしては、
特に難しいことはないでしょう。同じ鍵を持っているので、同じデータに復元で
きるという簡単なことです。
シンプルであり、共通鍵が「秘密」である限り、共通鍵暗号は安全です。しか
し、共通鍵暗号を利用する場合、ひとつの相手に対してひとつの鍵を保持してお
かなければなりません。つまり、複数のクライアントを相手にする場合、サーバ
側はそのクライアントの数だけ共通鍵を用意する必要があります。同じ鍵を別々
のクライアントに使うことはできませんから。というわけで、共通鍵暗号は鍵の
管理が問題になります。ただ、とりあえず安全性は共通鍵が「秘密」である限り
保証されます。
このような共通鍵暗号方式を使っている有名な暗号アルゴリズムにDES(Data
Encryption Standard)やRC4(Rivest's Cipher 4)といったものがあります。
■0x04.) 公開鍵暗号
共通鍵暗号と比べて、公開鍵暗号は少しややこしいです。というよりも、理解
に苦しみます(^^;。共通鍵暗号とは、要するに、それぞれが同じ鍵を持っている
わけですから、当然同じように暗号化、復号化ができることは普通に納得できま
す。
しかし、公開鍵暗号とは、暗号化と復号化を別々の鍵で行わなければなりませ
ん。つまり、「aaaa」という鍵で暗号化したデータは、同じ「aaaa」という鍵で
は復号化できないのです。では、何の鍵で復号化できるのかというと、それは、
あらかじめ「aaaa」と対(つい)になって作成された「zzzz」という鍵です。
つまり、公開鍵暗号では、次のようなことが可能になります。
+-- server ------------------------------------------------+
| 鍵「aaaa」と「zzzz」を作成し、鍵「aaaa」を相手に送信 |
+----------------------------------------------------------+
↓鍵「aaaa」
+-- client ------------------------------------------------+
| 鍵「aaaa」を使って平文「BBBB」を暗号化 |
+----------------------------------------------------------+
まずサーバが2つの対となる鍵を生成します。そして、その片方の鍵をクライア
ントへ送信します。クライアントはその鍵を受け取って、その鍵で平文を暗号化
します。この時点で暗号文が生成されます。その暗号文をサーバへ送ります。
+-- client ------------------------------------------------+
| 平文「BBBB」を暗号化した暗号文「CCCC」を相手に送信 |
+----------------------------------------------------------+
↓平文「BBBB」を鍵「aaaa」で暗号化した暗号文「CCCC」
+-- server ------------------------------------------------+
| 暗号文「CCCC」を鍵「zzzz」で復号化し、平文「BBBB」を得る |
+----------------------------------------------------------+
暗号文を受け取ったサーバは、その暗号文をあらかじめ対(つい)として作成
していた鍵「zzzz」を使って復号化します。これによって、平文「BBBB」を得る
ことができます。
さて、ここで問題となるのが、ネットワークを流れる、鍵「aaaa」と暗号文「
CCCC」の2つの情報から、平文を求めることができるのか? というところですが、
答えはNoです。ただし、暗号化を行うことはできます。つまり、誰もがみんな、
鍵「aaaa」を使って暗号化をすることはできますが、それから平文を復号化する
ことはできないわけです。
この、鍵「aaaa」のことを「公開鍵」、そして、それと対(つい)になって作
成された鍵「zzzz」を「秘密鍵」と呼びます。公開鍵は暗号化のための鍵ですか
ら、誰に教えても構いません。よって、ネットワーク上を流しても問題ありませ
んし、Webページで公開しても問題ありません。しかし、秘密鍵は復号化するため
の鍵ですから、これは自分以外誰にも知られてはならないわけです。
また、公開鍵暗号の特徴として、多くのクライアントを相手にしていても、鍵
が1組(「公開鍵」と「秘密鍵」の2つ)でよいことが挙げられます。共通鍵暗号
の場合は、クライアントの数だけ鍵を用意する必要がありましたが、公開鍵暗号
の場合は、「公開鍵」と「秘密鍵」の1組だけでよいのです。つまり、すべてのク
ライアントに同じ公開鍵を渡し、それで暗号化されたデータを受信して、自分だ
けの秘密鍵で復号化することができます。ここは共通鍵暗号よりもすぐれたとこ
ろでしょう。
ちなみに、「なぜ別々の鍵で暗号化や復号化が行えるのか」という問題に関し
ては、私も分かりません。暗号理論を勉強してください(^^;。
このような公開鍵暗号方式を使っている有名な暗号アルゴリズムにRSA(Rives
t Shamir Adleman「発案者3名の頭文字」)といったものがあります。
■0x05.) ハッシュ
暗号と関連した話題で「ハッシュ」というものがあります。ハッシュとは「あ
るデータ」を「ある計算」によって「ある値に変換させたデータ」のことです。
文字にするととても分かりにくいですが、簡単に言えば、「あるデータ」を「AA
AA(0x41414141)」として、「ある計算」を「1バイト単位に区切って加算する」
とします。すると、これらから導かれるハッシュは「A + A + A + A = 0x41 * 4
= 0x0104」となります。つまり、「AAAA(0x41414141)を1バイト単位に区切っ
て加算すると0x104になる」といういたって簡単なことです。
ただし、暗号とハッシュには、大きな違いがあります。それは、復号化できる
か否かです。暗号化されたデータは必ず何かしらの方法で平文を復元できなけれ
ばなりません。それでなければ、そもそも暗号化の意味がありません。しかし、
ハッシュは復号化できなくても良いのです。というか、むしろ復号化できてはい
けません。しかし、復号化できなければ、それはただ、データを変換しただけの
状態であり、何の意味もないように思えます。が、実はハッシュには十分な利用
価値があります。
データを変換しただけのハッシュ値というものを、いったい何に使用するのか
というと、一般的には「高速な検索」及び「データの検証」に使用されるようで
す。例えば、膨大な文書(仮に100ギガバイトとする)があり、それが正確なもの
かどうかを調べたい場合、最初の1バイトからひとつずつ、終端100ギガバイト目
まで調べていくのは大変です。しかし、あらかじめこの膨大な文書のハッシュ値
を計算しておけば、そのハッシュ値を調べるだけで、その文書が正確なものであ
るかどうかを評価することができます。
MD5のハッシュ値は必ず16バイトなので、100ギガバイトを調べる必要はなく16
バイトのみを評価するだけで、その文書が正確なものかどうかを確認できます。
つまり、ハッシュ値とは「データの要約」と考えることができます。
あくまでも「データの要約」なので、ハッシュ値から元のデータが復元できて
はいけませんし、また、なるべく短いデータ列でなければいけません。そして、
入力値が異なれば、当然ハッシュ値も(なるべく)異なるものになるアルゴリズ
ムでなければならないのです。これがハッシュアルゴリズムの性質です。
現在、もっとも有名なハッシュアルゴリズムに、MD5(Message Digest 5)やS
HA1(Secure Hash Algorithm 1)といったものがあります。
■0x06.) 暗号通信
「共通鍵暗号」「公開鍵暗号」そして「ハッシュ」、プログラマが知っておく
べきことは、このくらいで問題ありません。知識としても、このくらいの概念を
理解しておけば大丈夫です。あとは、それっぽいライブラリを使ってそれっぽい
プログラムを書いていけば、大体のことはつかめてくるはずです(ホントかよ^^;
)。まぁ我々はプログラマですから、理論よりも実践、プログラムを書いてナン
ボです(笑)。というわけで、これらの知識をうまく利用して、現在の暗号通信
の実装を考えていくことにします。
さて、実際にインターネット上で暗号通信を行う場合、「共通鍵暗号方式がよ
いか?」「公開鍵暗号方式がよいか?」で迷うところですが、現在もっとも一般
的なものは、「最初の通信のみ公開鍵暗号方式を使い、以後の通信は共通鍵暗号
方式を使う」というものです。
そもそも共通鍵暗号というのは、通信を行うそれぞれが同じ鍵を持っていなけ
ればなりません。しかし、そうなると、「そもそも、共通となる鍵をどうやって
受け渡すのか?」という問題にぶつかります。例えば、田中さんと鈴木さんがイ
ンターネットを利用し、暗号通信でメールの送受信を行う場合、それぞれに一度
も面識がなかったら、そもそも共通となる鍵を持つことができません。しかし、
それでは、暗号通信が出来ません。
というわけで、どうにかして共通鍵を相手に送る必要があります。つまり、共
通鍵暗号方式の最大の問題点である、「どうやって共通鍵をそれぞれが持ってい
るという状態を作りだすか」というところに行き着くわけです。
そこで、公開鍵暗号を使って、共通鍵暗号の「共通鍵」の受け渡しを行います。
+-- 田中さん ----------------------------------------------+
| 公開鍵暗号用の公開鍵「aaaa」と秘密鍵「zzzz」を作成 |
| そして、公開鍵「aaaa」をクライアントへ送信 |
+----------------------------------------------------------+
↓公開鍵「aaaa」
+-- 鈴木さん ----------------------------------------------+
| 共通鍵暗号用の共通鍵「kkkk」を作成 |
| 受け取った公開鍵「aaaa」を使って共通鍵「kkkk」を暗号化 |
+----------------------------------------------------------+
まずは送信側(この例では田中さん)が公開暗号の「公開鍵」と「秘密鍵」を
作成します。そして、公開鍵を相手(この例では鈴木さん)へ送信します。次に、
公開鍵を受け取った鈴木さんは、その鍵で、共通鍵暗号の「共通鍵」を暗号化し
ます。つまり、共通鍵の受け渡しに公開鍵暗号方式を利用するのです。
+-- 鈴木さん ----------------------------------------------+
| 共通鍵「kkkk」を暗号化した暗号文「mmmm」をサーバへ送信 |
+----------------------------------------------------------+
↓暗号文「mmmm」
+-- 田中さん ----------------------------------------------+
| 受け取った暗号文「mmmm」を秘密鍵「zzzz」で復号化し |
| クライアントが生成した共通鍵「kkkk」を得る |
+----------------------------------------------------------+
これで、田中さんと鈴木さんの双方に共通鍵「kkkk」が存在することになりま
す。そして、これ以後、双方はこの共通鍵「kkkk」を使って暗号通信を行うこと
が可能となります。
+-- 田中さん ----------------------------------------------+
| 平文「BBBB」を共通鍵「kkkk」で暗号化し、相手に送信 |
+----------------------------------------------------------+
↓平文「BBBB」を鍵「kkkk」で暗号化した暗号文「CCCC」
+-- 鈴木さん ----------------------------------------------+
| 受け取った暗号文「CCCC」を |
| 共通鍵「kkkk」で復号化し、平文「BBBB」を得る |
+----------------------------------------------------------+
つまり、最初の通信時に公開鍵方式を利用し共通鍵の受け渡しを行い、以後、
その受け渡しを行った共通鍵で通信を行うというわけです。これが、現在の一般
的な暗号通信のようです。
さて、ここでひとつの疑問が出てきます。それは「なぜ全部の通信を公開鍵暗
号方式で行わないのか?」ということです。共通鍵暗号方式の「鍵の受け渡しが
困難」という欠点は分かりましたが、では、「全部の通信を公開鍵で行えばよい
じゃないか?」という疑問が出てきます。確かにメールの場合はそれでもよいか
もしれませんが、残念ながら公開鍵暗号方式にも欠点はあります。それは「処理
速度が遅い」ということと「なりすましが可能である」という2点です。
まず、公開鍵暗号は、共通鍵暗号に比べて処理速度が数十倍も遅いのです。よ
って、大量の通信が発生する環境では、なるべく共通鍵暗号を利用した方がよい
のです。また、公開鍵暗号はその性質上、なりすましが可能になります。公開鍵
暗号方式は、暗号化を行うための公開鍵がその名の通り「公開されている」ため、
それを受信した誰もが暗号化を行うことができます。よって、正規の通信相手に
成り代わって、第三者が通信を行うことが可能です。公開鍵暗号は、誰もが暗号
化を行えること前提で成り立っているため、このような問題が発生します。
実は、この公開鍵暗号のなりすまし問題防止のために「署名」という仕組みが
あります。「署名」とは、送られてきたメッセージ(データ)が、本当に送信者
本人が作ったものであるかどうかを識別する仕組みです。この署名が正しいもの
であれば、送られてきたデータは正式なものであると判断できます。ただ「署名」
の説明は少々ややこしいので「暗号プログラミング 〜後編〜」で行うとして、
とりあえずは、これまで学んだ知識を使ってプログラミングを行うことにします。
一応タイトルも、暗号「プログラミング」なので(^^;。
■0x07.) OpenSSL
OpenSSL(http://www.openssl.org/)とは、SSL(Secure Socket Layer)とTL
S(Transport Layer Security)を実装し、電子証明書の発行や管理、S/MIME関連
のユーティリティなどを含んだ暗号化ライブラリである、ということらしいです
が、要するに、これ使っておけば、とりあえず暗号関連はモウマンタイというこ
とです。なので素直に使っておきましょう。
ちなみに、OpenSSLはオープンソースプロジェクトで大変有難いのですが、本家
のページに行くと、本当にソースコードだけで、バイナリがなかったりします。
よって、自分でコンパイルする必要がありますが、そのためには、どうやらPerl
とCコンパイラとASMコンパイラが必要なようです。Linux環境なら簡単ですが、W
indows環境でこれらをそろえるのは少々骨が折れます。というわけで、GNUライセ
ンスを最大限に利用して、Windows用のコンパイル済みバイナリ(DLLファイル、
LIBファイル、ヘッダファイル)をアップロードしました。コンパイルがメンドク
サイという方は使ってください。
http://ruffnex.oc.to/kenji/text/sslcrypt/openssl.zip
もし「自分でコンパイルするよ」という方は、OpenSSLのreadme辺りにコンパイ
ル方法が書いてありますので、それを参照してください。
■0x08.) 共通鍵暗号プログラミング(RC4)
RC4(Rivest's Cipher 4)とは、RSA Security社のRon Rivest氏によって開発
された共通鍵暗号方式のひとつで、ストリーム型と呼ばれる暗号化技術が採用さ
れています。DESなどのような一定のブロック単位で暗号化を行うブロック暗号に
対し、1ビット(もしくは1バイト)単位で暗号化を行うものをストリーム暗号と
呼びます。
暗号の世界では、「ストリーム暗号」と「ブロック暗号」という言葉をよく耳
にします。これらはいったい何かというと、ストリーム暗号とは、「1バイト(も
しくは1ビット)の平文に対して、1バイト(もしくは1ビット)の暗号文」が出力
されます。つまり、平文と暗号文のサイズは変わりません。そして、1バイト(も
しくは1ビット)単位で暗号化されていきます。しかし、ブロック暗号は、平文を
特定のサイズで区切って、その1区画ごとに暗号化処理を行うため、平文と暗号文
のサイズが変化する場合があります。
例えば、平文のサイズが18バイトだったとして、これを8バイト単位で区切ると、
8バイトのデータが2つと、2バイトのデータが1つになります。最初の2つの8バイ
ト区画はそのまま処理すればよいですが、残りの2バイトは8バイトに満たないた
め暗号化処理ができません。よって、暗号アルゴリズム側が、残りの6バイトに何
かしらのデータを付加(パディング)して8バイトとし、それを暗号化することに
なります。すると、結果的に暗号文は24バイトのデータとなります。
このように、8バイト単位で暗号化を行うブロック暗号方式だと、18バイトのデ
ータが24バイトに膨張することになります。このような暗号アルゴリズムをブロ
ック暗号と呼びます(区切るバイト数は暗号アルゴリズムによって異なる)。ち
なみに、当たり前ですが、復号化すると、24バイトの暗号文が18バイトの平文に
復元できます。
つまり、ストリーム暗号は、1バイト(もしくは1ビット)ごとに暗号化処理が
されていき、ブロック暗号は、特定のサイズごとに暗号化処理がされていくとい
う具合です。まぁあえて言い換えるなら、ストリーム暗号は「1バイト(もしくは
1ビット)単位で区切られたブロック暗号」とも言えるでしょう。
では、共通鍵暗号でストリーム暗号方式のRC4を使って、データの暗号化、復号
化を行うサンプルプログラムを見てください。
----- rc4test.cpp
#include
#include
#include
#pragma comment(lib, "libeay32.lib")
#pragma comment(lib, "ssleay32.lib")
int hexoutput(char *first_str, unsigned char *data, int len)
{
int i;
printf("%s", first_str);
for(i=0; i < len; i++)
printf("%02X", data[i]);
printf("\n");
return 0;
}
int main(int argc, char *argv[])
{
RC4_KEY rc4key;
unsigned char encryptdata[1024], decryptdata[1024];
int datalen;
if(argc < 3){
fprintf(stderr, "%s \n", argv[0]);
return 1;
}
datalen = strlen(argv[2]);
hexoutput("KEY = ", (unsigned char *)argv[1], strlen(argv[1]));
hexoutput("PLAIN = ", (unsigned char *)argv[2], datalen);
RC4_set_key(&rc4key, strlen(argv[1]), (unsigned char *)argv[1]);
RC4(&rc4key, datalen, (unsigned char *)argv[2], encryptdata);
RC4_set_key(&rc4key, strlen(argv[1]), (unsigned char *)argv[1]);
RC4(&rc4key, datalen, encryptdata, decryptdata);
hexoutput("ENCRYPT = ", encryptdata, datalen);
hexoutput("DECRYPT = ", decryptdata, datalen);
return 0;
}
-----
----- コマンドプロンプト
C:\>bcc32 -w rc4test.cpp
Borland C++ 5.6.4 for Win32 Copyright (c) 1993, 2002 Borland
rc4test.cpp:
Turbo Incremental Link 5.65 Copyright (c) 1997-2002 Borland
C:\>rc4test test AAAAAAAA
KEY = 74657374
PLAIN = 4141414141414141
ENCRYPT = EFCE6650A16B3C64
DECRYPT = 4141414141414141
C:\>
-----
第1引数に鍵となる文字列、第2引数に平文を渡すと、暗号化と復号化を行いま
す。正確に暗号化と復号化がなされていることが分かります。
OpenSSLで暗号化アルゴリズムを利用するためには、RC4_set_key関数とRC4関数
を使います。これらはrc4.hにて次のように定義されています。
----- RC4_set_key関数
void RC4_set_key(
RC4_KEY *key, // RC4_KEY構造体アドレス
int len, // 鍵データのサイズ
const unsigned char *data // 鍵データのアドレス
);
-----
RC4_set_key関数はRC4_KEY構造体を作成するための関数です。鍵データを入力
することで、それを元にした構造体を作成することができます。一般的に、プロ
グラム上では鍵データは構造体に変換されます。構造体が鍵としての機能を担う
ので、共通鍵方式では双方が同じ構造体を持っていれば通信が可能ということに
なります。
----- RC4関数
void RC4(
RC4_KEY *key, // RC4_KEY構造体
unsigned long len, // 平文のサイズ
const unsigned char *indata, // 平文のアドレス
unsigned char *outdata // 暗号文を格納するバッファ
);
-----
RC4関数は、実際に暗号化(復号化)を行う関数です。RC4_set_key関数で作成
した構造体と、平文を渡すことで暗号文を出力してくれます。ちなみに、RC4は暗
号化処理と復号化処理が同じアルゴリズムとなっています。つまり、RC4関数に暗
号文を入れると、平文を出力してくれることになります。
■0x09.) 公開鍵暗号プログラミング(RSA)
RSAとは、1977年にRon Rivest氏、Adi Shamir氏、Leonard Adleman氏の3人によ
って開発された公開鍵暗号方式のことです。公開鍵暗号のアルゴリズムとしては
最もよく知られた方式であり、多くの製品に採用されています。事実上、暗号ア
ルゴリズムのスタンダードだと言えます。
RSAは、整数の素因数分解などを利用して暗号化を施します(詳しくは知りませ
ん^^;)。現在も有効な解読方法が見つからないということで、もっとも実用的な
アルゴリズムのようですが、処理速度が遅いという欠点もあります。
次にRSA暗号を利用したサンプルプログラムを示します。
----- rsatest.cpp
#include
#include
#include
#pragma comment(lib, "libeay32.lib")
#pragma comment(lib, "ssleay32.lib")
int hexoutput(char *first_str, unsigned char *data, int len)
{
int i;
printf("%s", first_str);
for(i=0; i < len; i++)
printf("%02X", data[i]);
printf("\n");
return 0;
}
int main(int argc, char *argv[])
{
RSA *rsa_s, *rsa_c;
unsigned char encryptdata[1024], decryptdata[1024];
int datalen;
if(argc < 2){
fprintf(stderr, "%s \n", argv[0]);
return 1;
}
datalen = strlen(argv[1]);
// make private key & public key
rsa_s = RSA_generate_key(256 * 2, RSA_F4, NULL, NULL);
hexoutput("PLAIN = ", (unsigned char *)argv[1], datalen);
rsa_c = RSA_new();
BN_hex2bn(&(rsa_c->e), BN_bn2hex(rsa_s->e)); // copy public key e
BN_hex2bn(&(rsa_c->n), BN_bn2hex(rsa_s->n)); // copy public key n
// encryption by public key
datalen = RSA_public_encrypt(datalen, (unsigned char *)argv[1],
encryptdata, rsa_c, RSA_PKCS1_OAEP_PADDING);
RSA_free(rsa_c);
hexoutput("ENCRYPT = ", encryptdata, datalen);
// decryption by private key
datalen = RSA_private_decrypt(datalen, encryptdata,
decryptdata, rsa_s, RSA_PKCS1_OAEP_PADDING);
RSA_free(rsa_s);
hexoutput("DECRYPT = ", decryptdata, datalen);
return 0;
}
-----
----- コマンドプロンプト
C:\>bcc32 -w rsatest.cpp
Borland C++ 5.6.4 for Win32 Copyright (c) 1993, 2002 Borland
rsatest.cpp:
Turbo Incremental Link 5.65 Copyright (c) 1997-2002 Borland
C:\>rsatest AAAAAAAA
PLAIN = 4141414141414141
ENCRYPT = 4456BC68D656821AE97EA4511CF7AAF042A41FBDFF3EAE8285CEE94AA9C5398EF9787F
511869E5425EB603A5349D2E84A7222DDFD2EC3201DCD4AC0B2146FDFA
DECRYPT = 4141414141414141
C:\>
-----
RSAは、最初に2つの対(つい)となる鍵を生成します。この2つの鍵(公開鍵と
秘密鍵)はRSA_generate_key関数で作成します。
----- RSA_generate_key関数
RSA *RSA_generate_key( // 戻り値はRSA構造体ポインタ
int bits, // 鍵のビット長
unsigned long e, // 公開指数(RSA_3 or RSA_F4)
void (*callback)(int,int,void *), // よく分からないのでNULL
void *cb_arg // よく分からないのでNULL
);
-----
引数の説明がかなり適当で申し訳ないです。実は自分もよく分かってません。
ただ、bitsは鍵のビット長(512, 1024, etc...)を指定するということと、eは
何かとても重要な値(公開指数と呼ぶらしい)で、通常「3」か「65537」を指定
するらしいです。他はNULLで問題ないでしょう(^^;。これで戻り値にRSA構造体の
アドレスが返ります。
そして、このRSA構造体には、公開鍵と秘密鍵が格納されています。よって、構
造体の中にある公開鍵を取り出して、相手に送らなければなりません。RSA構造体
の中の公開鍵はeとnです。よって、eとnを取り出して別のRSA構造体に渡します。
----- RSA_new関数
RSA *RSA_new(void); // 戻り値はRSA構造体アドレス
-----
RSA_new関数は、空のRSA構造体を作成してくれます。この構造体に公開鍵eとn
をコピーします。そして、RSA_public_encrypt関数を呼び出します。
---- RSA_public_encrypt関数
int RSA_public_encrypt( // 戻り値は成功時に暗号文サイズ
int flen, // 平文サイズ
const unsigned char *from, // 平文アドレス
unsigned char *to, // 暗号文を格納するバッファ
RSA *rsa, // 公開鍵を持つRSA構造体アドレス
int padding // パディング指定
);
-----
この関数は、公開鍵を使って平文を暗号化します。RSAはブロック暗号なので、
パディングを指定する必要があります。一般的にはRSA_PKCS1_OAEP_PADDINGが使
われるようです。ちなみに、パディング方法は、暗号化する側と復号化する側で
同じものにしておかなければなりません。
----- RSA_private_decrypt関数
int RSA_private_decrypt( // 戻り値は成功時に平文サイズ(パディング含む)
int flen, // 暗号文サイズ
const unsigned char *from, // 暗号文アドレス
unsigned char *to, // 平文を格納するバッファ
RSA *rsa, // 秘密鍵を持つRSA構造体アドレス
int padding // パディング指定
);
-----
引数はRSA_public_encrypt関数とほとんど同じです。この関数で、秘密鍵を利
用しての復号化を行います。
----- RSA_free関数
void RSA_free (
RSA *r // RSA構造体アドレス
);
-----
RSA_generate_key関数とRSA_new関数は、共にRSA構造体のメモリ領域確保しま
す。よって、RSA_free関数で解放してやる必要があります。これで、後始末は終
了です。
■0x0A.) ハッシュ生成プログラミング(MD5)
MD5(Message Digest 5)とは、認証や署名などに使われるハッシュ関数のひと
つです。固定サイズ(16バイト)のハッシュ値を生成します。
次にMD5のハッシュ値を生成するプログラムを示します。
----- md5test.cpp
#include
#include
#include
#pragma comment(lib, "libeay32.lib")
#pragma comment(lib, "ssleay32.lib")
int hexoutput(char *first_str, unsigned char *data, int len)
{
int i;
printf("%s", first_str);
for(i=0; i < len; i++)
printf("%02X", data[i]);
printf("\n");
return 0;
}
int main(int argc, char *argv[])
{
unsigned char encryptdata[16];
if(argc < 2){
fprintf(stderr, "%s \n", argv[0]);
return 1;
}
MD5((unsigned char *)argv[1], strlen(argv[1]), encryptdata);
hexoutput("PLAIN = ", (unsigned char *)argv[1], strlen(argv[1]));
hexoutput("ENCRYPT = ", encryptdata, 16);
return 0;
}
-----
----- コマンドプロンプト
C:\>bcc32 -w md5test.cpp
Borland C++ 5.6.4 for Win32 Copyright (c) 1993, 2002 Borland
md5test.cpp:
Turbo Incremental Link 5.65 Copyright (c) 1997-2002 Borland
C:\>md5test test
PLAIN = 74657374
ENCRYPT = 098F6BCD4621D373CADE4E832627B4F6
C:\>
-----
ハッシュの生成は、さほど難しい知識を必要としないので、プログラムも簡単
です。使用するのは、MD5関数のみです。
----- MD5関数
unsigned char *MD5(
const unsigned char *d, // 入力データのアドレス
size_t n, // 入力データのサイズ
unsigned char *md // ハッシュ値の格納アドレス
);
-----
入力データには、どれだけのサイズのデータを入れても問題ありません。どん
なサイズのデータを入れても、結果として出力されるハッシュ値は必ず16バイト
となります。そして、このハッシュ値は基本的にどんなデータとも重複しません。
■0x0B.) さいごに
このように、OpenSSLを利用すると、最低限の知識で暗号を利用することが可能
となります。また、OpenSSLには、RSAやRC4の他にも数多くの暗号アルゴリズムが
実装されていますし、オープンソースですので、ソースコードも読み放題です。
もし、暗号に興味を持ったなら、一度暗号について調べてみるのもよいかもしれ
ません。
ちなみに、本当にコアな暗号理論を学びたい方はIPUSIRONさんのテキストを読
んでください(^^;。一応、私も「暗号プログラミング 〜前編〜」と題してお送
りしましたが、正直、暗号理論の内容としては、初歩の初歩です。というか、暗
号に関する私の知識も大したものではないので、そもそも初歩の初歩しか教えら
れないのですが、ただ、プログラマが知っていなければならない部分くらいは、
なんとか踏み込んでやろうと考えていますので、来月の「暗号プログラミング
〜後編〜」もよろしくお願いします(^^;。
というわけで、今回の記事、楽しんでいただけたなら幸いです。最後になりま
したが、ここまで読んでくれて本当にありがとうございます。
では、また会う日まで...
x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x
x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x
--- 第5章: 基礎暗号学講座 〜 第4回 〜 ---
著者:IPUSIRON
x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x
x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x
■0x01.) はじめに
前回のWBではブロック暗号の利用モードとして、ECBモードとCTRモードの2つを
解説しました。今回は残りのCBCモード・CFBモード・OFBモードについて解説する。
そして最終的にどの利用モードを採用するほうがよいのかを言及します。
■0x02.) CTRモードの問題の答え合わせ
前回のWBの第4章の0x07において、CTRモードと情報理論的な安全性についての
問題を出しました。まず新しいことを学ぶ前に軽く復習しておきましょう。全然
意味がわからないという方は気軽に雑談掲示板に質問してください。実際きちん
と追っていけばそれほど難しいことはしていません。
問:CTRモードについて、次の設問を解け。
(1)平文M=(m_1,m_2)に対する暗号文がC=(ctr,c_1,c_2)であった。このときの
E_k(ctr+1)およびE_k(ctr+2)の値を求めよ。
(2)ランダム関数族をブロック暗号として用いるCTRモードを考える。アタッカ
ーが暗号文C=(ctr,c_1,c_2)を入手した。このとき、平文が(m_1,m_2)である確率
を求めよ。
(3)ランダム関数族をブロック暗号として用いたCTRモードは、情報理論的に安
全であることを証明せよ。
(4)ランダム置換族をブロック暗号として用いるCTRモードを考える。アタッカ
ーが暗号文C=(ctr,c_1,c_2)を入手した。このとき、平文が(m_1,m_2)である確率
を求めよ。
(5)ランダム置換族をブロック暗号として用いたCTRモードは、情報理論的に安
全でないことを証明せよ。
まず(1)から解いていきます。カウンターモードの暗号化では、平文M=(m_1,
…,m_t)に対して、c_1=m_1+E_k(ctr+1),…,c_t=m_t+E_k(ctr+t)を計算します。わ
かりやすいように縦に並べてみましょう。
c_1=m_1+E_k(ctr+1)
c_2=m_2+E_k(ctr+2)
…
c_t=m_t+E_k(ctr+t)
ただし問題の中では平文はm_1とm_2だけなので実質2つの式だけしかありません。
c_1=m_1+E_k(ctr+1)
c_2=m_2+E_k(ctr+2)
ここで+はXOR演算であることを思い出します。XOR演算の特徴として同じものを
足し合わせると消えるというのがあります。例えば6+6=0になるわけです。2進数
で考えればこれは明らかです。101と101をXOR演算したとします。XOR演算は0+0=
0,0+1=1,1+0=1,1+1=1であるので、101+101=000になります。
上に列挙した中で一番最初の式を変形していきます。
c_1=m_1+E_k(ctr+1)
c_1+m_1=m_1+m_1+E_k(ctr+1) (∵両辺にm_1をXOR演算する)
c_1+m_1=E_k(ctr+1) (∵m_1+m_1=0)
E_k(ctr+1)=c_1+m_1 (∵右辺と左辺を入れ替えた)
同様に2番目の式を変形していきます。
c_2=m_2+E_k(ctr+2)
E_k(ctr+2)=c_2+m_2
次に(2)を解きます。(2)の問題文が云わんとすることは、「M=(m_1,m_2)∧
C=(ctr,c_1,c_2)」が成り立つ確率を求めなさいということです。つまり、次のよ
うに計算していくことができます。
Pr(M=(m_1,m_2)|C=(ctr,c_1,c_2))
=Pr(E_k(ctr+1)=c_1+m_1,E_k(ctr+2)=c_2+m_2)
=Pr(E_k(ctr+1)=c_1+m_1)・Pr(E_k(ctr+2)=c_2+m_2)
=(1/2^n)・(1/2^n)
=1/2^(2n)
ところで、数学の問題が小さい問が連続して出題されているときは、前の問題
がヒントになっていることが多いです。ここでも(1)の答えを使って、上記の式
変形の1つ目から2つ目に式変形しています。
3つ目から4つ目の変換で実際に確率計算しています。前半の「Pr(E_k(ctr+1)=
c_1+m_1)=1/2^n」部分を見ていきましょう。c_1やm_1はnビットなので、それをX
OR演算したc_1+m_1はnビットです。つまりc_1+m_1の総パターンは2^n通りです。
これがE_k(ctr+1)とちょうど一致するのは、1/2^nとなります。後半のPr(E_k(ct
r+2)=c_2+m_2)=1/2^n」部分も同様に考えればよいです。
それでは(3)を解きます。その前に情報理論的に安全という意味を復習してお
きましょう。前回のWBから抜粋しておきます。
[定義]
∀c∈C、∀m∈M;Pr(~M=m|~C=c)=Pr(~M=m)
が成り立つとき、暗号系(~K,~M,~C)は情報理論的に安全(完全秘匿)であると
いう。
(図)http://s-akademeia.sakura.ne.jp/main/image9/jyouhou.jpg
つまり、アタッカーが暗号文を手に入れた状態から平文を推測成功する確率と、
何も手に入れない状態から平文を推測成功する確率が一致すれば、情報理論的に
安全ということです。つまりアタッカーは暗号文を手に入れても、平文に関する
情報を何も得ていることにならないということです。
よって(3)示したいことは次が成り立つことになります。
Pr(M=(m_1,m_2))=Pr(M=(m_1,m_2)|C=(ctr,c_1,c_2))
ここで平文は一様分布していていることに注意しておきましょう。そうすると
左辺は次のように求めることができます。
Pr(M=(m_1,m_2))=Pr(M=m_1,M=m_2)=(1/2^n)・(1/2^n)
一方、右辺は(2)より次が成り立つことはすでに判明しています。
Pr(M=(m_1,m_2)|C=(ctr,c_1,c_2))=(1/2^n)・(1/2^n)
よって確率が等しくなったので、情報理論的に安全であることが示せました。
次に(4)を考えます。
E_kは置換でctr+1≠ctr+2なので、E_k(ctr+1)≠E_k(ctr+2)となります。これは
置換の性質から明らかです。置換の性質上、違う値を入れて置換すると、その結
果も異なることになります。E_k(ctr+1)≠E_k(ctr+2)ということは、(1)から右
辺と左辺を書き換えることができて、c_1+m_1≠c_2+m_2になります。
次のように2つに場合分けができます。
[1]c_1+m_1=c_2+m_2のとき
Pr(M=(m_1,m_2)|C=(ctr,c_1,c_2))
=Pr(E_k(ctr+1)=c_1+m_1,E_k(ctr+2)=c_2+m_2) (∵(1))
=Pr(E_k(ctr+1)=c_1+m_1)・Pr(E_k(ctr+2)=c_2+m_2)
=(1/2^n)・(1/(2^n-1))
再度の式変形には注意してください。前半部で総パターンの2^n通りのうちから
ひとつが決定したので、後半部では総パターンから1を引いたもの総パターンにな
ります。図にすると次のようになります。
(図)http://s-akademeia.sakura.ne.jp/main/image9/ctr_keisan.jpg
[2]c_1+m_1≠c_2+m_2のとき
Pr(M=(m_1,m_2)|C=(ctr,c_1,c_2))
=0
最後に(5)を考えます。今度は(3)のようにランダム関数族ではなく、ラン
ダム置換族を使う場合です。本当の暗号ではこんなことはしませんが、あくまで
理解を確かめるためにあえてランダム置換族にするということです。このように
条件を若干変更して、結果がどう変わってくるのかを自分で確かめるということ
は非常にためになります。暗号の仕様だけを追いかけていても何にもなりません。
この暗号が情報理論的に安全であるには次が成り立たなければなりません。
∀c∈C,∀m∈M;Pr(M=(m_1,m_2)|C=(ctr,c_1,c_2))=Pr(M=(m_1,m_2))
しかし、(4)から必ずしも成り立たないので(場合分けの結果が異なっている
ので明らか)、情報理論的に安全でないことになります。
少し解説が長くなってしまいましたが、どうでしたでしょうか? それほど難
しい数学などは使っていません。あくまで「情報理論的に安全」「関数と置換の
違い」「ビット列がある特定のビット列に一致するときの確率の求め方」の3つを
しっかり理解しておけば、類似問題は完璧に解けることになることでしょう。あ
まりこの辺の話をしっかり書いている本が少ないので(書いてあっても文字列ば
かりで抽象的過ぎたりする)、ここはしっかり理解しておいて欲しいと思います。
それでも理解できないとしても、以降の話がわからないということではないので
安心してください。。
■0x03.) CBCモード
CBC(Cipher Block Chaining:暗号ブロック連鎖)モードとは、次の仕様にし
たがい各m_iを暗号化する方式です。
[1]暗号化
平文M=(m_1,…,m_t)に対して、nビットの初期化ベクトルIV(Initial Value)
をランダムに選び、c_1=E_k(IV+m_1),c_2=E_k(c_1+m_2),…,c_t=E_k(c_t-1+m_t)
を計算して、暗号文をC=(c_1,…,c_t)とします。
[2]復号
暗号文C=(IV,c_1,…,c_t)に対して、m_1=D_k(c_1)+IV,m_2=D_k(c_2)+c_1,…,m
_t=D_k(c_t)+c_t-1を計算して、平文をM=(m_1,…,m_t)とします。
(図)http://s-akademeia.sakura.ne.jp/main/image9/cbc.jpg
mとcでE_kを挟んだような仕組みになっています。このE_kがなければ一種の関
数と見れます。
特徴としてIVを定数(ブロック暗号の処理を施す度に)とすると安全でなくな
ります。IVを定数にしてしまうと、ある平文を決まった鍵で暗号化したときと同
じになってしまい、いつも暗号文が同じになってしまいます。例えばアタッカー
がターゲットの通信路をずっと監視していたとします。そのとき同じ暗号文が1週
間ごとの決まった時間に傍受したとします。通常規則性のある時間に同じ暗号文
が流れてくる確率はほとんどありません。それにも関わらずそのような規則性が
あるということは、同じ平文を通信していて、しかもそれに対応する暗号文が同
じになってしまうという欠陥のある暗号を利用していると推測できます。後はこ
の情報からどんどん情報が漏れていく可能性があります。
またIVをカウンターモードにおけるctrのようにインクリメントするような設計
にしてもなりません。これも同様に考えればよいわけなので、最後に宿題として
います。
■0x04.) CFBモード
CFB(Cipher Feed Back:暗号フィードバック)モードとは、次の仕様にしたが
い各m_iを暗号化する方式です。
[1]暗号化
平文M=(m_1,…,m_t)に対して、nビットの初期化ベクトルIV(Initial Value)
をランダムに選び、c_1=m_1+E_k(IV),c_2=m_2+E_k(c_1),…,c_t=m_t+E_k(c_t-1)
を計算して、暗号文をC=(c_1,…,c_t)とします。
[2]復号
暗号文C=(IV,c_1,…,c_t)に対して、m_1=c_1+E_k(IV),m_2=c_2+E_k(c_1),…,m
_t=c_t+E_k(c_t-1)を計算して、平文をM=(m_1,…,m_t)とします。復号アルゴリズ
ムD_kではないことに注意。
(図)http://s-akademeia.sakura.ne.jp/main/image9/cfb.jpg
図から平文ブロックは暗号アルゴリズムによって直接暗号化されないというこ
とがわかります。
CFBモードで暗号アルゴリズムが生成するビット列のことを鍵ストリームと呼び
ます。CFBモードでは鍵ストリームを生成するための擬似乱数生成器として暗号ア
ルゴリズムを用いています。IVは擬似乱数生成器の種に相当します。
なおE_kは置換である必要がありません。
■0x05.) OFBモード
OFB(Output Feed Back:暗号フィードバック)モードとは、次の仕様にしたが
い各m_iを暗号化する方式です。
[1]暗号化
平文M=(m_1,…,m_t)に対して、nビットの初期化ベクトルIV(Initial Value)
をランダムに選び、
z_1=E_k(IV),z_2=E_k(z_1),…,z_t=E_k(z_t-1)
c_1=m_1+z_1,c_2=m_2+z_2,…c_t=m_t+z_t
を計算して、暗号文をC=(c_1,…,c_t)とします。
[2]復号
暗号文C=(IV,c_1,…,c_t)に対して、
z_1=E_k(IV),z_2=E_k(z_1),…,z_t=E_k(z_t-1)
m_1=c_1+z_1,m_2=c_2+z_2,…,m_t=c_t+z_t
を計算して、平文をM=(m_1,…,m_t)とします。復号アルゴリズムD_kではないこと
に注意。
(図)http://s-akademeia.sakura.ne.jp/main/image9/ofb.jpg
図から平文ブロックは暗号アルゴリズムによって直接暗号化されないというこ
とがわかります。平文ブロックと暗号アルゴリズムの出力とをXOR演算して、暗号
ブロックを作り出します。OFBモードはこの点でCFBモードに似ています。
IVは暗号化の度ごとに異なるランダムビット列を用いるのが普通です。
なおE_kは置換である必要がありません。
■0x06.) 各種利用モードの比較
以上でブロック暗号の主要な利用モードのすべての解説が終りました。
実際にブロック暗号を設計するときはCBCモード・CTRモードの使用が推奨され
ています。実際にインターネットではCBCモードがよく登場しています。
最後に関連する定理を少しだけ紹介します。この定理の証明は余力のある方だ
けで十分だと思います。
[定理]
ECBモード以外の各モードは、{E_k}が擬似ランダム置換族であると仮定すると、
選択平文攻撃に対して安全である。
[定理]
CTRモードが最も安全である。
■0x07.) 宿題
今回の解説したことを理解したかを確認のために、宿題として2つの問題を示し
ておきます。
問:次の設問を解け。
(1)CFBモードで、IVをカウンターモードにおけるctrのようにインクリメントす
るような設計にするとどのような問題が発生するか?
(2)CFBモードでは暗号化の度ごとに異なるランダムビット列を用いなければ安
全ではありません。一方OFBモードでは暗号化の度ごとに異なるランダムビット列
を用いるのが普通と言及しました。そこで実際にOFBモードではどのような問題が
発生するか?
■0x08.) おわりに
次回はブロック型の最大の特徴であるFeistal型構造について解説する予定です。
最後に少し宣伝。現在アカデメイアではSASというオンラインゼミを開催してい
ます。
http://akademeia.info/index.php?SAS2006
現在行っている題材はグラフ理論ですが、ネットワーク理論や暗号理論などあ
らゆる分野に係わってきます。真面目に習得しようという意欲のある方は是非メ
ールでお知らせください。もちろん現段階の数学の能力はゼロでもまったく問題
ありません。実際に高校生なども参加しています。気軽に声をかけてください。
それでは来月会いましょう。
x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x
x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x
--- 第6章: 基礎暗号学講座 〜 第5回 〜 ---
著者:IPUSIRON
x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x
x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x
■0x01.) はじめに
今回は多くのブロック暗号で採用されているFeistel型構造を解説します。
■0x02.) Feistel型構造
[定義]
次のようなブロック暗号の構造をu段のFeistel型構造と呼ぶ。第i番目のF_iは{0
,1}^nから{0,1}^nへの関数である。各F_iはラウンド関数と呼ばれる。
http://s-akademeia.sakura.ne.jp/main/image9/Feistel1.jpg
u段のFeistel型構造への入力(L0,R0)で表すことにする。ただし、L0∈{0,1}^n、
R0∈{0,1}^nである。またi=1,…,uに対して、L_i=R_i-1,R_i=L_i-1+F_i(R_i-1)と
おく。このとき出力は(L_u,R_u)で表される。
■0x03.) 理想化した場合
[定義]
長さ2nの擬似ランダム置換族からランダムに選ばれた擬似ランダム置換と呼ぶ。
同様に長さnの擬似ランダム関数族からランダムに選ばれた関数を擬似ランダム関
数と呼ぶ。
すでに擬似ランダム置換と擬似ランダム関数についてはWB27で定義しています。
注意して欲しいのは前者では長さが2nビットであり、後者では長さがnビットと
いうことです。
前者はなぜ長さnについて触れているかというと、Feistel型構造の入力がL0(
nビット)とR0(nビット)の2つなので合計で2nビットになっているからです。ま
た逆関数は任意のラウンド関数F_iについて成り立ちます。逆関数が存在するので
Feistel型構造は任意のラウンドF_iについて{0,1}^2nの置換であることがわかり
ます。
一方、後者はなぜ長さnについて触れているかというと、ラウンド関数F_iの入
力はnビット、出力がnビットです。しかし逆関数は存在するとは限りません。よ
って置換ではなく関数にしているわけです。
ここで知りたいことは、Feistel型構造において各F_iが完全な擬似ランダム関
数であると理想化したとき、u段のFeistel型構造(ψ(F1,…,F_u)と表記される)
は擬似ランダム置換になるかということです。
段数がu段という一般の話から取り組むのは難しいので、まず2段のときから考
えていきます。こういったアプローチは数学においてよく使われます。つまり具
体的な例から始めて、いくつかサンプルを取ってから定理の一般化するわけです。
[問題1]2段のFeistel型構造は擬似ランダム置換になるか?
定義の関係式にi=2を代入すると次の関係式が成り立ちます。
L2=R1=L0+F1(R0)
[1]入力(L0,R0)を(0^n,0^n)としたときの出力を(a,b)として調べます。
http://s-akademeia.sakura.ne.jp/main/image9/Feistel2.jpg
[2]次に入力(L0,R0)を(1^n,0^n)としたときの出力を(a',b')として調べます。
http://s-akademeia.sakura.ne.jp/main/image9/Feistel3.jpg
ここでa+a'を調べます。
a+a'
=(0^n+F1(0^n))+(1^n+F1(0^n))
=0^n+F1(0^n)+1^n+F1(0^n)
=0^n+1^n (∵F1(0^n)+F1(0^n)=0)
=1^n
a+a'=1^nが成り立つかどうかをチェックし、成り立てば1、そうでなければ0を
出力する識別アルゴリズムDを考えます。これを図にすると次のようになります。
http://s-akademeia.sakura.ne.jp/main/image9/Feistel4.jpg
なお置換πを利用する識別アルゴリズムDのことをD^πと記述することにします。
このとき置換πがψ(F1,F2)の場合は必ずa+a'=1^nが成り立つので、100%の確率で
Dは1を出力します。
P_A
=Pr(D^π=1)
=1 ←(*) D^πが1を出力する確率が1という意味
一方、置換πが長さ2nのランダム置換族からランダムに選ばれた場合に、a+a'
=1となる確率は次のように計算できます。
P_random
=Pr(D^π=1)
=Pr(a+a'=1)
={2^(2n)×2^n×(2^(2n)-2)!}/{2^(2n)}! ←(**)
=(2^n)/(2^(2n)-1)
<2/(2^n) ←(***)
(**)の計算は次のように行った。このような解法は講座の第4回目で言及したは
ずです。
http://s-akademeia.sakura.ne.jp/main/image9/Feistel5.jpg
よって、(*)(***)よりDの識別利得(アドバンテージ)は次のように計算できま
す。
Adv(D)=|P_A-P_random|>1-2/(2^n)
つまり十分大きいということになります。nを無限大に持っていけば、2/(2^n)
は0になるので、識別利得は1に近づきます。
ゆえに擬似ランダム置換族にならないことがわかりました。
では3段ではどうでしょうか。これは擬似ランダム置換となることが示されてい
ます。証明は各自の課題としておきます。
■0x04.) 強擬似ランダム
普通の擬似ランダムの概念とは異なり、強擬似ランダムという概念がFeistel型
構造と関連してきますので、解説します。
まず強擬似ランダム置換とは次のように定義されます。
[定義]
長さ2nのランダム置換族P_2nの部分集合A_2nが、選択暗号文攻撃(CCA)において
もP_2nと識別困難なとき、A_2nを長さ2^nの強擬似ランダム置換族と呼ぶ。
この定義に関連して、次のような結果がわかっています。これは結果だけ示し
ておきます。
[定理]
(1)3段のFeistel型構造は強擬似ランダム置換にはならない。
(2)4段のFeistel型構造は強擬似ランダム置換になる。
■0x05.) おわりに
今回はFeistel型構造の基本だけについて解説しました。基本だけでしたがきち
んと計算問題をこなせば、それ以上の概念が出てきたとしてもすんなりと理解で
きることでしょう。この置換とか関数が絡んだときの確率計算にまだ慣れていな
い方はWB2を復習しておいてください。
来月はMAC(Message Authentication Code)について解説する予定です。MACは
共通鍵暗号系のメッセージの正真性(改ざんを検知)を確かめるための仕組みで
す。
x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x
x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x
--- 第7章:お知らせ ---
x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x
x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x
○Wizard Bible(http://wizardbible.org/)では随時、執筆ライターを募集して
います。
扱う内容のテーマは広義での「under ground」です。例えば、ハッキングから
サリンガスの合成法などと幅広い内容を考えています。また、各種、特殊な職業
や趣味を持った方のレクチャーなども含まれます。
一回きりでも構いません。また、必ず、毎回連載する義務もありませんのでで
きる範囲で構いません。気軽に声をかけてください。もちろん一回書いたことが
ある人も気軽に声をかけてください(全く気にしていない性格なので)。
○Kenji AikoさんがQ&Aを作ってくれました。初めて参加する人でもわかりやすく
書かれていますので、参考にしてください。
http://wizardbible.org/wbQandA.html
○支援者、参加希望者用のスレッドを立てました。
http://ruffnex.oc.to/ipusiron/cgi/forum/patio.cgi?mode=view&no=17
x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x
x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x
---- 第8章:著者プロフィール ---
x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x
x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x
■金床
●Job: プログラマー
●Web: http://guardian.jumperz.net/, http://www.jumperz.net/
●Mail: anvil@jumperz.net
●HNの由来:
DiabloというネットワークRPGでANVILというキャラクターでプレイしてました
(ANVIL自体は響きを思いついて決めた名前)。その後RPGの世界なら「ANVIL」も
いいんだけど普通にネット上で使うのはどうもなぁ…ということで英単語「anvil」
の意味である「金床」にしたわけです。読みはいちおう「かなとこ」なんですが
別に「きんゆか」でもいいです。ハンドルネームが漢字って人は少ないのでちょ
っといいかも(何がいいんだかw)。
■Kenji Aiko
●Job: Reverse Engineer
●Web: http://ruffnex.oc.to/kenji/
●Mail: kenji@ruffnex.oc.to
●Team(Group): N/A
●Comment:
「時間がないというけれど、時間がないなら作ればよいじゃないか」というど
こかのエライ人の格言を信じて、一生懸命時間を作る努力をしていますが、なか
なかうまくいきません。やっぱり人間には24時間しか与えられてないのだなぁと
つくづく感じます(^^;。
●HNの由来
由来もなにも本名です(^^;。HNは本名なのでリアル社会でもこの名前で生きて
います。しかも結構珍しい名前だと思うので、探すのも簡単だと思います(ぉぃ。
■IPUSIRON
●Job: Student
●Web: http://akademeia.info/
●Mail: ipusiron@ruffnex.oc.to
●Team(Group): N/A
●Comment:
そろそろ修士論文の準備をしなければならない時期になってきました。研究テ
ーマの方向性と目標は明確にあるので、後はそれに関連する最新の論文をチェッ
クしつつ、基礎を固めていき、自分の研究の目標のために思考し続けるだけです。
来年には学会とかに発表できるぐらいになっておきたいです。
●HNの由来:
イプシロン(ε)は数学で一番使われるギリシャ文字で(大学以上の数学では
本当によく出てくる)、愛着があって10年ぐらい前から使い続けています。スペ
ルをローマ字にしているのは、英語のイプシロンだと読めない人が多いと単純に
思ったからです。