[-]=======================================================================[-] Wizard Bible vol.50 (2010,4,22) [-]=======================================================================[-] x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x ---- 第0章:目次 --- x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x ○第1章: マニアックJavaプログラミング第12回: 〜 セッションをCookieに格納する 〜 金床 著 ○第2章: ピッキングの雑学 その2 IPUSIRON 著 ○第3章: お知らせ ○第4章: 著者プロフィール x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x --- 第1章: マニアックJavaプログラミング第12回: 〜 セッションをCookieに格納する 〜 --- 著者:金床 x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x ■0x01.) はじめに  今回はウェブアプリのセッション管理についてである。Tomcatなどで動作するJava 製ウェブアプリを作る場合、普通はCookieにJSESSIONIDという名前のセッションIDの みを格納し、実際のセッションの内容はサーバ側で管理する。デフォルトではセ ッションの内容はメモリ上に保持され、Tomcatを終了する際にはファイルに保存 されたりする。この方式は基本的に問題なく動作するのだが、障害に備えて、あ るいは性能を上げるためにロードバランサを使ってTomcatを冗長化しよう、とい うことになると、とたんに話が面倒くさくなる。複数のTomcatインスタンス間で セッション情報を共有する必要があるため、単にメモリ上に持っているだけでは だめなのだ。Tomcatにはこのような場合に備えたクラスタリングの機能が実装さ れているのだが、どうにも設定などが面倒くさそうだし、動作もややこしそうで ある。そこでセッションの内容を全部Cookieに、つまりブラウザ側に丸投げして しまうことでサーバ側で楽をしてしまう、ということを考える。  セッションの内容をすべてブラウザに渡してしまえば、ロードバランサの背後 にTomcatがいくついても大丈夫だ。HTTPリクエストは必ずセッションオブジェク トとセットで到達するため、どのTomcatインスタンスがリクエストを受信しても、 ウェブアプリケーションはきちんと動作することができる。ロードバランサーも、 セッションIDを見て振り分ける先を考えたりせず、Tomcatが生きているかどうか だけ考えて適当に分散してしまえばいい。また、Tomcatインスタンスの増減も好 きなタイミングで行うことができる。実に素晴らしいソリューションなのだ。 ■0x02.) セッション管理 エボリューション  セッション管理において、10年くらい前のまだウェブアプリが「CGI」と呼ばれてい たころには、セッションの内容をそのままCookieに格納する方式は珍しくなく、 むしろ主流だった。しかしPHPやJavaがセッションIDのみをCookieに格納し、オブ ジェクト自体はサーバ側で管理するという仕組みをフレームワークの一部として 提供するようになったため、いつしかこの方式は使われなくなっていった。  しかし2007年頃になって、Ruby製の非常に有名なWAFであるRuby on Rails(以 下RoR)では、セッションの内容をすべてCookieに格納する動作をデフォルトとす るようになった。これは見た目の動作としてはまるで昔に戻ってしまったかのよ うであるが、筆者の個人的な見解としては、むしろ進化のひとつであると思って いる。  ウェブアプリケーションは10年前に比べて圧倒的に多数のユーザに使われるよ うになり、またそのユーザの増加の度合いもより急激になったため、ウェブアプ リケーションを作る際には「スケールアウトできる」アーキテクチャであること が重要になった。セッション管理は多くのウェブアプリケーションで必須の機能 のひとつであり、スケールアウト可能であることが求められる。冒頭で説明した ように単にサーバがメモリ上にオブジェクトを保持している場合、アプリケーシ ョンサーバが複数になった場合にスケールアウトできない。RDBMSなどに格納すれ ば複数のインスタンスで共有することはできるが、耐えられるアクセスはそれほ ど多くない。そのためmemcachedなどにセッションオブジェクトを格納するテクニ ックが広まることとなった。  しかし、もっと簡単な方法があるのだ。ユーザが大量になればなるほど、それ に伴って増えるストレージがある。そう、Cookieだ。また、アクセスしてくるユ ーザが自身のデータも一緒に運んでくることになるため、RDBMSやmemcachedなど で行うような「セッションIDをキーにしてデータを引っ張ってくる」必要もない。 スケールアウト時代のWAFであるRoRがCookieをセッションオブジェクトの格納先 に選ぶのは非常に自然なことだと考えられる。 ■0x03.) 従来の方法とCookie格納方式との違い  セッションオブジェクトをCookieに格納する場合、従来のサーバ側で管理する 方法と比べて、どのような違いがあるだろうか。  まず、サイズに制限がある。サーバ側ではストレージを大量に用意すればどの ようなサイズのオブジェクトでも保持することができるが、Cookieには上限が存 在するため、それほど大量のデータを保持することはできない。  次に、セキュリティの問題がある。10年前のCGIプログラムによくあったような プレーンテキストで丸見えのデータをCookieに格納してしまうと、改ざんされた りする可能性がある。そのため、基本的にはサーバ側で管理されたキーで暗号化 を行うのがよいだろう(RoRでは暗号化は行わず改ざん防止のハッシュ値添付だけ を行っているようだが、3rdパーティ製の暗号化ライブラリも存在している)。  セッションの有効期限については、Cookieを使う場合でもサーバ側から管理す ることができる。セッションオブジェクトの一部に有効期限の数値を入れておき、 毎アクセスごとにサーバ側でそのセッションの有効期限が切れていないかを確か めればよいのだ。そのためこの点については違いはない。サーバ側で管理しない と有効期限をコントロールできないように思う人がいるかもしれないが、Cookie を使う場合でも問題なく古いセッションは(実質的に)破棄できる。 ■0x04.) 開発のコンセプト  それでは具体的な実装を考えていくことにする。筆者は自分で開発するウェブアフ ゜リケーションについてはごくシンプルな自作のWAF(フレームワークのほう)を使っている。今 回あるプロジェクトにおいてTomcatをクラスタリングしたいというケースに遭遇 したため、セッション処理を一部追加開発し、前項までに説明したようなCookie にセッションオブジェクトを格納する方式を選べるようにした。その際以下のよ うな点を念頭に開発を行った。 ・ウェブアプリケーション自体のコード(以下アプリ処理)は従来と変えずに済む ようにする。ごく普通にsesisonオブジェクトにsetAttributeしたりgetAttribut eしたりすることでセッションの内容にアクセスする。 ・アプリ処理よりも前に、Cookieからセッションの内容を取り出して、復号やデシリアライゼ ーセホンなどを行い、sessionオブジェクトに格納する処理をおこなう ・アプリ処理の後に、sessionオブジェクトから内容を取り出して、シリアライゼーションや暗号 化を行い、Set-Cookieヘッダを発行する処理をおこなう ・一般的にCookieにはサイズの上限(4KB)が存在するが、これはひとつひとつの Cookieについてである。複数のCookieを並列的に使うことでこの上限を10〜15倍 程度まで増加させる ・セッションの内容はシリアライズした後にGZIPで圧縮を行い、効率よくデータ を格納する ■0x05.) Javaでの実装例  なお、先述の通り自作WAFであるため、以下のコードでは一部の処理が標準的な サーバサイドJavaとは異なっている点に注意してほしい。セッションは通常java x.servlet.http.HttpSessionインターフェースを継承したクラスが使われるが、 筆者の自作WAFでは単にMapとなっている。  まず、アプリ処理の後にセッションオブジェクトの内容をCookieに格納する処理を行う関数 である。 ----- public static void setClientSession( Map sessionParameters, HttpServletResponse response, MBlowfishCBCCipher cipher, int timeout ) throws IOException { -----  引数には先述したMap型のセッション(既に中身は入っているもの)、サーブレットレスポン ス、暗号化処理を行うユーティリティクラス、そしてセッションの有効期限を意味 するtimeoutである。 ----- //set expiration datetime sessionParameters.put( CLIENT_SESSION_EXPIRE_KEY, ( System.currentTimeMillis() + ( timeout * 1000 ) ) + "" ); -----  有効期限を表す時刻をセッション内に格納しておく。後にクライアントから送 られてきた際にこの値をチェックすれば、サーバ側で古いセッションを破棄(拒 否)することが可能になる。 ----- //serialize ByteArrayOutputStream bo = new ByteArrayOutputStream(); ObjectOutputStream oo = new ObjectOutputStream( new GZIPOutputStream( bo ) ); oo.writeObject( sessionParameters ); oo.close(); byte[] plainData = bo.toByteArray(); -----  セッションの内容をシリアライズしてバイト配列にする。このときGZIPOutput Streamを使うことでGZIP圧縮も同時に行ってしまう。ストリームとして書き込ん だ後にバイト配列として取得できるByteArrayOutputStreamが非常に便利である。 ----- //encrypt byte[] encData = cipher.encrypt( plainData ); String encStr = Base64.encodeBytes( encData, false ); -----  暗号化し、Base64でCookieに格納しやすくする。この処理の実装は本稿では省 略する。 ----- //set cookie String remain = encStr; for( int i = 0; i < CLIENT_SESSION_COOKIE_COUNT; ++i ) { if( remain.length() > CLIENT_SESSION_COOKIE_LENGTH ) { String _str = remain.substring( 0, CLIENT_SESSION_COOKIE_LENGTH ); Cookie cookie = new Cookie( CLIENT_SESSION_KEY + i, _str ); cookie.setPath( "/" ); response.addCookie( cookie ); remain = remain.substring( CLIENT_SESSION_COOKIE_LENGTH ); } else if( remain.length() > 0 ) { Cookie cookie = new Cookie( CLIENT_SESSION_KEY + i, remain ); cookie.setPath( "/" ); response.addCookie( cookie ); remain = ""; } else { Cookie cookie = new Cookie( CLIENT_SESSION_KEY + i, "" ); cookie.setPath( "/" ); response.addCookie( cookie ); } } } -----  この部分の処理はややわかりにくいので、単純化した例を使って説明する。Co okieに格納したいデータが小さければ、単に以下のようにすればよい。 ----- Set-Cookie: foo=bar -----  しかし今回はウェブアプリケーションから汎用的に使用するセッションオブジェクトとな るため、(圧縮後の)サイズが4KBよりも大きい場合にも対応したい。そのため複 数のCookieに分散することでこれを可能にする。たとえばCookieのデータの上限 サイズが6バイトだったら、「ABCDEFGHIJKL」という文字列は格納できない。しか し以下のように2つのCookieに分ければ格納することができる。 ----- Set-Cookie: foo1=ABCDEF Set-Cookie: foo2=GHIJKL ...(以下同様) -----  次にHTTPリクエストが送られてくるときには、以下のようなCookieヘッダとな る。 ----- GET / HTTP/1.0 Host: www.jumperz.net Cookie: foo1=ABCDEF; foo2=GHIJKL -----  サーバ側ではfoo1とfoo2の値をそれぞれ取得してから結合することで「ABCDEF GHIJKL」という文字列を取得できる。Cookieの数にも上限(20個?)があり、ま た最近ではアクセス解析用に使われるGoogleAnalyticsなどがいくつかのCookieを 使用してしまうこともあるため、ここで分散するために使用するCookieの数は10 程度にしておくのがよいだろう。この場合でも実質的に40KB程度のセッションデ ータをCookie格納することができるため、多くのケースで十分なサイズとなるだ ろう。  次にブラウザから送られてくるHTTPリクエストからCookieを取り出し、セッシ ョンオブジェクトの内容を復元する処理を見ていく。 ----- private static Map getClientSessionImpl( HttpServletRequest request, MBlowfishCBCCipher cipher ) throws IOException, ClassNotFoundException { -----  関数の定義はこのようになっており、Map型のセッションオブジェクトを返すよ うになっている。引数はサーブレットリクエストと暗号化ユーティリティクラス のインスタンスだ。 ----- Cookie[] cookies = request.getCookies(); if( cookies == null ) { return new HashMap(); } -----  Cookieがリクエスト中に存在していなければ中身が空のHashMapインスタンスを 返す。 ----- String[] buffer = new String[ CLIENT_SESSION_COOKIE_COUNT ]; for( int i = 0; i < cookies.length; ++i ) { Cookie cookie = cookies[ i ]; String name = cookie.getName(); if( name.indexOf( CLIENT_SESSION_KEY ) == 0 ) { int index = MStringUtil.parseInt( MRegEx.getMatch( "[0-9]{1,}", name ) ); if( index < CLIENT_SESSION_COOKIE_COUNT ) { buffer[ index ] = cookie.getValue(); } } } StringBuffer buf = new StringBuffer(); for( int i = 0; i < CLIENT_SESSION_COOKIE_COUNT; ++i ) { String str = buffer[ i ]; if( str != null ) { buf.append( buffer[ i ] ); } } -----  先述の通り複数のCookieに分散して格納されているため、それをStringBuffer クラスを用いてひとつのデータとして繋げる。 ----- if( buf.length() > 0 ) { byte[] encData = Base64.decode( buf.toString() ); byte[] plainData = cipher.decrypt( encData ); ByteArrayInputStream bi = new ByteArrayInputStream( plainData ); ObjectInputStream oi = new ObjectInputStream( new GZIPInputStream( bi ) ); Map sessionParameters = ( Map )oi.readObject(); -----  Base64のデコード処理に続いて復号処理をおこない、さらにGZIPInputStreamを 使ってGZIP圧縮を展開する。そしてデシリアライゼーションをおこない、Map型のセッションオブ ジェクトとして取り出す。 ----- //check expiration try { long validUntil = Long.parseLong( ( String )sessionParameters.get( CLIENT_SESSION_EXPIRE_KEY ) ); if( System.currentTimeMillis() > validUntil ) { System.out.println( "client session expires." ); return new HashMap(); } } catch( Exception e ) { e.printStackTrace(); return new HashMap(); } return sessionParameters; } return new HashMap(); } -----  最後に有効期限をチェックして終了となる。 ■0x06.) まとめ  今回はウェブアプリケーションにおけるセッション管理の方法について、クラウド/NoSQL時代 に合った方法であるCookieへの格納の実装例について解説した。既にRoRではデフ ォルトになっており、今後多くのフレームワークがCookieをセッションオブジェクトの格納先に選 んでいくのは間違いないだろう。筆者も時間があればTomcatに対してより簡単に この実装が適用できるようなフィルタなどを開発してみたいと思っている。 x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x --- 第2章: ピッキングの雑学 その2 --- 著者:IPUSIRON x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x ■0x00.) はじめに  セキュリティアカデメイア内のピッキング講座を一時休止にしてから、新たに知 った内容も増えてきたので、今回はその一部をWBで紹介したいと思う。  読者の前提としてはピンシリンダー錠のピッキングの原理がすでに理解できてい るものとしている。  具体的には錠前や鍵の各部の名称を知っていること、テンションをかけてシアラ インを揃えれば開錠できること、テンションをかけているときはすべてのドライバ ーピンが外筒に当たっているのではないことなどが把握できていれば十分である。 ■0x01.) ピッキングの雑学 ●ピッキングに成功したはずなのに途中で内筒が動かなくなるのはなぜか  これはピッキング対象の錠前に依存して理由が異なる。  ピンタンブラー錠であればおそらく180度回転したところで動かなくなったので はないだろうか(180度回さないで閂が解除されるものもあるが、それらは除外す る)。もしそうであれば、ドライバーピンが内筒のくぼみに落ち込んでしまった からである。これはトラブルでもなんでもなく、通常起こりうることである。原 因を一から説明する。  まず、ピンタンブラー錠のピッキングに成功してシアラインを揃え、内筒を開 錠方向に回していく。このとき、内筒の6時方向(真下)に存在した部分も内筒を 回すと同時に、回っていく。実はこの部分は完全に切り抜かれていており、合鍵 を挿している上体であれば鍵の背中がある部分になる。つまり、鍵の背中が外筒 に触れつつ1回転(360度回転)すると開錠される。今はピッキングをして内筒を 回転させているため、鍵の背中に相当するものがない。その状態で180度回転する と、そこにドライバーピンがばねの力で落ち込んでくるのである。ドライバーピ ンが落ち込めば、回転すると外筒にぶつかってしまい、回転を戻そうとしても進 めようとしても動かなくなってしまう。原理がわかれば推測できると思うが、合 鍵と同じように背中に相当する状態を作ってやればよいのだ。テンションの長い 方を奥まで垂直に入れて、上に上げればドライバーピンは同時に持ち上がる。後 はシアラインよりも上にドライバーピンがすべて上げておきつつ、内筒を回せば よい。そうすれば、開錠が成功する。  ディスクシリンダー錠の場合は90度回転、45度回転中に動かなくなることがあ る。これはディスクシリンダー錠の外筒リングの構造による。両面ディスクシリ ンダー錠の場合、通常外筒リングには2つの大きな切込みがある(両面だから最低 2つの穴)。なぜならばここにディスクが出て、ディスクが出ている状態で内筒を 回そうとしてもひっかかって回らないのである。合鍵を入れるとディスクがすべ て内筒に収まり、外筒リングにひっかかるディスクがすべて存在しないので内筒 が回るのである。  つまり外筒リングに穴がたくさん開いていればいるほど、内筒の回転中にまた 穴からディスクが飛び出し、ピッキングを行う再度行う羽目になるのである。  鍵の先端がサムターンと連動するタイプの錠前で、この種の外筒リングを使っ ている場合であれば、内筒が回ったら次の穴にディスクが到達する前に一旦停止 し、奥のロックを解除する道具を入れつつ、内筒を戻してやればよい。開錠の目 的はドアの閂をはずすこと、即ちここではサムターンを回転させることである( このとき最終的に開錠方向回すのが目的であることに注意)。よって、内筒を完 全に回すことが目的ではないのである。実際にMIWAの両面ディスクシリンダー錠 の場合はいくら内筒を回転させても、奥のロックを解除しない限りデッドボルト は動かない。ゆえに、シアラインが揃って内筒が少しでも回れば、後はロック解 除ツールを奥の溝にひっかけて開錠方向に回すことができればよいのである。  車のディスクシリンダー錠にもテンションで内筒を回転しているときに、何回 (大抵2,3回)か止まるものもある。その度にピッキングをやり直して、完全に開 錠方向に回せばよい。 ●ピックガン  ピッキングをやり始めると欲しくなるのがピックガンではないだろうか。見た 目にも格好いいが、正直使いものになるのかどうかを考察している。  ピックガンは引き金を引くと先端の接続したピックが上下に1回震動する。ピン タンブラー錠の鍵穴にピックガンのピックを適切な角度で入れた状態で引き金を 引けば、すべての下ピンが跳ね上がる。つまり、下ピンに押されて、ドライバー ピンも同時に上がるので、瞬間的にシアラインが揃う。もちろんテンションをか けていなければ、すべての下ピンはドライバーピンに押されたまま内筒側に戻っ てくる。これはピンタンブラー錠の原理から明らかである。よって、テンション をかけた状態で、ピックガンの先端を鍵穴に入れて引き金を引けばよいのである。 瞬間的にシアラインが揃ったところでテンションをかけた内筒が回る。  ピックガンを使えば同時にピンを上げるということは、各ピンの長さの違いが 大きいと、瞬間的にシアラインが揃いにくいのである。要するに、ピンの長さに 余り変化がない(合鍵の鍵山の高さが大きな変化が少ない)ときに、ピックガン による開錠の成功率が高いということになる。  鍵山の高さに違いがないならば、ピックガンでなくても普通のピッキングでも 開錠しやすいのでピックガンは不要と言いたいところだが、役に立つ場面もある。 ピンシリンダー錠のピッキング防止ピンが使用されている場合である。これは( 下)ピンの形がI型になっていたり、茸型になっていたりする。こうしたピンが存 在する場合、テンションをかけつつピッキング防止ピンをピックで上げても、ピ ッキング防止ピンが内筒と外筒の段差にひっかかり、ピッキング防止ピン自身が そこから上に上げることができない。結果的にドライバーピンも外筒側に移動す ることができず、シアラインが揃えにくいのである。手動のピッキングの場合は 1ピンずつシアラインに揃っていくため(レーキングであっても瞬間的には1ピン ずつ揃っていく)、いつかはピッキング防止ピンを上げることになる。ピッキン グ防止ピンがひっかからない程度にテンションを緩めるという方法もあるが、緩 めすぎると逆にせっかくシアラインに揃え終えたドライバーピンが落ちてきてし まう。つまり、ピッキング防止ピンがあるピンシリンダー錠のピッキングはテン ションの力加減を調整する経験が必要となるのである。  ところがピックガンであればすべてのピンが上に押しあがる。つまり、ピック 防止ピンがあったとしても、内筒と外筒の段差にひっかかる前に上に押し出され てしまうのである。よって、ピック防止ピンの有無にかかわらず瞬間的にシアラ インが揃い、開錠できるのである。  ピックガンの先端に接続しているピックを自動的(ひきがねをひかずに電源を 入れるだけ)かつ連続的に振動するようにしたのが電動ピックガンである。効率 の面からいえば、電動ピックガンのほうがよいかもしれないが、思った以上の音 がする。  なお、ピックガンの先端の上下運動の幅は後ろのつまみで調整可能である。電 動ピックガンの場合はものによっては調整できないので注意。 ●逆テンションツール  通常テンションをかけるときは開錠方向と同じ方向に回転させるようにするこ とが多い。なぜならば開錠方向に回さなければ最終的にデッドボルトがはずれな いからである。  しかし、シリンダー内のピン配置によっては開錠方向ではなく、その逆にテン ションをかけた方がシアラインを揃えやすいことがある。  開錠方向と逆方向にテンションをかけてシアラインが揃い、内筒が開錠方向と は逆に回ったとする。後は開錠方向に内筒と回したいところだが、それを手動で 行うと鍵穴が最初にあった位置を通過しようとしても、ドライバーピンが落ちて くる方が早い。また施錠されてしまうのである。  そこで使うのが逆テンションツールである。スピナーとも呼ばれる。逆テンシ ョンツールを使えば、時計回り・逆時計回りのどちら方向にでも瞬間的に回転さ せることができる。つまり、ドライバーピンが落ちてくるよりも早く内筒を回転 させることができるのである。  逆テンションツールを用意すれば、次のようなアプローチでピッキングをする ことができる。  開錠方向に回るようにテンションを掛けてピッキングを試み、なかなかうまく いかなければ、逆にテンションを掛けてピッキングを試みる。そしてシアライン が揃って内筒が開錠方向と逆に回り始めたら、ちょっとだけ開錠方向と逆に回っ たところで止める(回しすぎたら完全に元に位置に戻る手前まで戻す)。そこで テンションを抜き、代わりに逆テンションツールを入れる(開錠方向の回るよう にセッティング完了した状態)。そして逆テンションツールを作動させれば、瞬 間的に開錠方向に内筒が移動する。少しでも鍵穴が最初の位置にあったところよ りも開錠方向に回転されていれば成功である。後はテンションで開錠方向にまわ していけばよい。 ●インプレッション  コピー対象の鍵がない状態で、コードブックなども使用せずに合鍵を作ってし まう方法である。特にディスクシリンダー錠が対象になる。  ブランクキーを用意して、ヤスリで表面のメッキを削っておく。特に鍵山がで きる側(鍵の背中の逆)を磨いておく。磨き終わったら、鍵穴に入れて、開錠方 向に軽く回す。当然ながら内筒は回らない。内筒が回らないというのはディスク が外筒リングの穴から出て、ひっかかっている。その状態でキーを回しているの でディスクに内側の壁面にキーがぶつかる。つまり、キーの鍵山があるべき位置 に傷が付くのである。  キーを引き抜いて、傷が付いたところを棒ヤスリなどで少し削る。これを繰り 返して、正しい鍵山を作ってしまうのである。  根気が必要な作業であり、失敗して削りしすぎてしまうとやり直しになってし まうため、一般的に難しい技術とされている。  傷を見やすいようにブランクキーに煤を付けるという方法もある。自分なりに 工夫をするとよいだろう。 ●内筒を回す方向(開錠方向)がわからない  デッドボルトの位置と鍵穴の位置から判別可能である。ドアが右勝手(ドアの 左側からデッドボルトが出ていて、右側に蝶番がある)であり、デッドボルトの 垂直線の下側に鍵穴があれば、開錠方向は時計回り(右回り)である。内筒の回 転方向に合わせて、ドッドボルトが引っ張られていくと思えばよい。  なお、ドアと壁の間のデッドボルトが見づらかったり、デッドボルトと鍵穴の 位置がほぼ水平位置であるときは、錠前の型番から判断したり、ロックオフの感 触などで判断する。この辺は経験になってくると思う。 ●バンピング  バンピングの技術自体は古くからあったが、泥棒たちが使い始めたこととピッ キングに強いとされていたディンプル錠にも通用するため、近年話題になってい る開錠方法である。  バンプキーを鍵穴に入れて、バンプキーを軽く回した状態でハンマーを叩く。 すると、上ピンが一斉に上に上がり、瞬間的にシアラインが揃う。そのため、内 筒が回る。  バンピング用のハンマー(バンプキーハンマーあるいはバンプハンマーという) も売られているが、ドライバーの柄などで叩いても問題ない。  普通ピッキングではピックとテンションを使用し、特にテンションの力加減が 重要となる。そのため、ピッキングでは経験が必要とされる。  一方、バンピングの場合はバンプキーそのものがテンションとして働く。バン プキーを軽く回すだけで、テンションがかかっている状態となる。そのためバン プキーさえ用意すれば、テンションの力加減がわからない初心者であっても簡単 にバンピングできるのである。  バンピングであればどんな錠前でも誰でも開錠できるわけではないことに注意。 原理を知ってしまえばわかるはずだがピンシリンダー錠に対しては有効であり、 ディスクシリンダー錠に対しては有効ではない。また、バンピングの対策を施し ている錠前もすでに存在する。 ●バンピングキーの入手  一番手っ取り早いのが海外の通販サイト(ただし、日本国内に発送ができなか ったり、相手と交渉が必要だったりする場合がある)である。しかし、ほとんど が海外の錠前に対するバンプキーしかなかったり、ディンプルのバンプキーは少 なかったりする。  よって、自分でバンプキーを作ったほうが早い。従来のピンシリンダー(多列 ではないタイプ)であればブランクキーをヤスリで削れば作れる。ただし鍵穴の 高さやスタートピッチ、ピッチを知らなければ、どこをどのように削ればよいか わからない。理想はコードブックを用意することである。コードブックが用意で きなければ、すでに鍵溝を削ってある鍵を参考にすれば、ピッチやスタートピッ チが判別できる。削るときの鍵山の高さは、その鍵の最上位段差で削る。例えば、 鍵山の高さの種類が8.0mm(0段差)、7.6mm(1段差)、6.9mm(2段差)の3種類で ある場合、2段差で削る。  またディンプルのバンピングキーをヤスリだけで作るのは大変なので、ディン プル用のコードマシンを用意する必要があるだろう。もちろん従来のピンシリン ダー錠のバンピングキーを作るときもコードマシンで作れば、ヤスリで作るより 効率かつきれいに作成できる。 ●メルティング(溶解破錠)  三才ブックスの『防犯マニュアル』に紹介されていて初めて知った。比較的最 近の開錠方法らしい。  弱酸性のある液体を鍵穴に流し込むことでタンブラーを溶かす開錠方法。電動 工具よる破錠では大きな音が発生するが、メルティングの場合はまったく音を立 てずに実行できる。実際に実験したいのでその弱酸性の液体が何なのか知ってい て、教えてもよいという方がいれば是非連絡ください。 ●八万ロックの開錠  八万ロックとは鍵穴が丸型の錠前である。例えば、バイクや自動販売機ではU字 型の外見を持っている。当然ながら八万ロックのシリンダーは円柱状であり、U字 型になっているか否かは閂を掛けたい対象に依存する。パチンコ台などでも使わ れていたと思う(最近パチンコに行ってないので記憶が曖昧)が、外からは鍵穴 しか見えない。  八万ロックの構造は、基本はピンシリンダー錠の構造と非常に似ている。鍵穴 を除くとでっぱりがいくつか見えるはずである。これが八万ロックのピンである。 通常、6ピンか7ピンある。見えているピンは鍵によって押し出されるピンであり、 ピンシリンダー錠でいえば下ピンに対応する。合鍵を入れると、ピンが奥に押さ れていき、シアラインが揃って内筒が回るのである。つまり、八万ロックをピッ キングするためには、開錠方向に対して内筒にテンションをかけて、1ピンずつ 特殊なピックで押して(当然バインドアンドフィール)、シアラインを揃えれば よいのである。テンションを軽くかけた状態では外筒とぶつかっているドライバ ーピンは1本である。ピックで1本ずつ押していき、ピンが戻ってくれば「はずれ」 、ピンが戻ってこないで少しテンションが回れば「当たり」である。これを繰り 返して、すべてのピンに対して行う。そして、シアラインが揃えば、内筒が回り、 開錠成功である。  通常の錠前で使用するテンションでも代用できるが、できれば専用のテンショ ンを用意したほうがよい。ピックの方は先端が曲がっていないものを使えばよい。 通常ピッキングツールセットには含まれないため、専用ピックを購入するか自作 する。針金を加工すれば簡単に作れる。  こうしたピックとテンションを使う方法が最も基本的だが、もっと効率的に開 錠するための道具が存在する。一般的な外見は、握り手に細い筒がつながってお り、その筒はちょうど丸型の鍵穴に入り、その周りにP字の針金が数本半固定され ている。P字型の針金の数は八万ロックのピン数と一致している。よって、八万ロ ックが7ピンを持つ場合は、7ピン用の道具でないといけないということである。 大抵は6ピンと7ピンのものが売られており、それぞれ80ドル〜120ドルぐらいする。 ピックとテンションを使う方法と基本は同じだが、この道具を使えば握り手をひ ねるだけでテンションがかかるので楽である。  またピンの位置をずれしたタイプも八万ロックも存在する(ピッチは等間隔だ が、スタートピッチがずれている)。この場合は上記の道具では対応できないの で、より上位の道具が必要になる。商品名はPKA2と呼ばれるものになる。価格は 結構高く、300ドル以上する。しかし、先ほど紹介した道具だとP字型の針金を半 固定にしてあるが結構繊細であり壊れやすい。よくここが壊れて輪ゴムで巻いて 修理している画像なども見る。PKA2の場合はねじで固定したり緩めたりすること ができるため、壊れにくい。また固定されている方が合鍵を作るときにもずれの 心配がないだろう。  八万ロックがボールペンの蓋で開錠できるという話もある。実際に試してはい ないが、原理からいえば、ピンの高さにあまりばらつきがなければ可能なはずで ある。これはピンの高さにばらつきが余りないピンタンブラー錠にはピックガン が有効であるという理由と同じである。  しかし、ちょうど鍵穴の直径に合い、かつ鍵穴の隙間に奥まで入るか蓋を探す 必要があるだろう。後者の条件はグラインダーやヤスリなどで削って加工すれば なんとかなりそうな気もする。  最終手段は破錠という選択肢がある。U字タイプの場合はU字のところを切れば よいと重いがちだが、大抵は超硬加工がされていて切りにくい。よって、ドライ バーピンをターゲットにする。  ところで通常のピンタンブラーであれば、ドライバーピンが存在する場所に合 わせてドリルで打ち抜いていく。ディンプル錠の場合はピンが多列になっている ので、列数分だけドリルで穴を開ける必要がある。  一方、八万ロックの場合は鍵穴が丸いという特徴を持つ。しかもその円周上に ドライバーピンが存在するのである。よって、この丸い鍵穴に沿って奥まで削っ ていけばすべてのドライバーピンが削れるわけである。つまり、電動ドリルに八 万ロック用(鍵穴にちょうど入るもの)のホールソーを取り付けて削っていけば よい。普通の錠前の場合はホールソーを使用して削るときにドリルがずれないよ うにする鍵穴に差し込む「先端」と呼ばれる道具も必要だが、八万ロックの場合 は鍵穴にホールソーが入るためドリルがずれることはないため先端は必要ない。 ●ケビン・ミトニックの名刺  ケビン・ミトニックの名刺にはピッキングツールが付属している。テンション が1本、ピックが4本付属している。その4本とはボールピック、フックピック、レ イクピック、ダイヤモンドピックである。いずれもピックの中でも使うものばか りなので(個人的にはボールよりもダブルボールが好き)、後は使いやすさの問 題が解決すれば、基本的なピッキングができるはずである。  そこで本当にピッキングができるのかを試してみた。結論から言うと、3ピン、 5ピンのピンタンブラー錠を開錠できました。しかし、付属しているテンションの 横幅が細いため、鍵穴にひっかけることに手間取ることと、テンションの長さも 短いため、テンションにかける指として小指が使いにくい。他の指にしてもよい がテンションに力がかかりやすくなる(普段から小指派じゃない人ならば問題な いが)。  ピックも同様に短いため、鍵穴の奥まで入れるが物理的に難しい。よって、ピ ン数が多いタイプはきついと思われる。また、必然的に持つ部分も短く、十分握 ることができないので、バインドアンドフィールで開錠するのは結構大変である。  一応ダイヤモンドピックやボールピックも付属しているので、ディスタンブラ ーも開錠できる。ロッカーのディスクタンブラーならば問題なく開錠できる。長 さの問題だけではなく、ピックの厚さが結構薄い方なので、ピック防止溝が入っ たディスクタンブラー錠はより難しい。 ■0x00.) 終わりに  今回紹介できなかった錠前や開錠方法などもたくさんある。例えば、金庫のダ イヤル錠、マグネット錠、車の錠前などである。これらについてもいつかWBで紹 介しようと思っているのでお楽しみに。  ではでは。 x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x --- 第3章: お知らせ --- x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x ○Wizard Bible(http://wizardbible.org/)では随時、執筆ライターを募集して います。  扱う内容のテーマは広義での「under ground」です。例えばハッキングやセキ ュリティからピッキングなどと幅広い内容を考えています。また特殊な職業や趣 味の解説などでも構いません。  一回きりでも構いません。また必ず毎回連載する義務もありませんので、でき る範囲で構いません。気軽に声をかけてください。 ○Kenji AikoさんがQ&Aを作ってくれました。初めて参加する人でもわかりやすく 書かれていますので、参考にしてください。 http://wizardbible.org/wbQandA.html ○Wizard Bibleに参加希望の方は気軽にメール(ipusiron@gmail.com)ください。 x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x ---- 第4章: 著者プロフィール --- x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x ■金床 ●Job: プログラマー ●Web: http://guardian.jumperz.net/, http://www.jumperz.net/ ●Mail: anvil@jumperz.net ●Comment:  アムスに逝ってから1年がたちました(1年たったのにWBが4号しか出ていないの はナゼだろうipuロム)。最近ipuロムがリア充になったのか何なのか、とにかくW Bが全然でなくなりました。アカデメイアの掲示板も絶賛放置プレイで、カタコトの日本語 スパム投稿などが横行しています。そのためボクが編集長の座を奪おうかと思い、 先日の怪しいイベントで「編集長漏れがやろうか?」と交渉したのですが、イヤそ うな顔をしていました(`Д´)ノ  IPUロムがWBを全然出さなくなった背景にはライター不足があるようで、募集し ても全然集まらないという状況が彼の編集長としての誇りを著しく傷つけている ようです。ということでみなさん読むだけでなく書いてくだちい。読み逃げ厳禁 !mixiか! ●関心のあるセキュリティ分野・技術:  そんなんウェブ周りにきまってんじゃん。漏れ「ウェブアプリケーションセキュリティ」とかい う本出してるくらいなんだからきくまでもないじゃん。という感じなのである。 最近はウェブサイトに感染するマルウェアがアツイのでマルウェア周りにも少し興味が出 てきました。 ■IPUSIRON ●Job: プログラマー ●Web: http://akademeia.info ●Mail: ipusiron@gmail.com ●Comment:  先月開催されたアングラナイトというイベントにおいて、「原稿が集まらなく 最悪2人だけの記事であってもリリースするべき」と金床さんに言われましたので、 勇気を出して今回リリースすることにしました。  年に4回のリリースではPhrackに追いつかないので、ちょっとスピード上げたい です。どんなネタでもよいので、WBの執筆者募集しております。 ●関心のあるセキュリティ分野・技術:  WBの記事の内容からも推測できると思いますが、最近は再び鍵・錠前について 興味がわいてきました。今後は電子錠や耐ピッキングの錠前が増え続けると思わ れますが、改めて追求してみるとまだまだやるべきことは残っていることに気付 きました。