Oct 30, 2007
[Misc] CAPTCHA の安全性についてメモ
CAPTCHA の安全性が話題になっているみたいなのでメモ。
- 凪瀬 Blog - はてなのCAPTCHAは簡単に破れる
- http://blogs.wankuma.com/nagise/archive/2007/10/26/104428.aspx
- Radium Software Development - Breaking CAPTCHAs with NNs
- http://www.radiumsoftware.com/0611.html#061110
- 高木浩光@自宅の日記 - 飾りじゃないのよCAPTCHAは 〜前代未聞のCAPTCHAもどき
- http://takagi-hiromitsu.jp/diary/20060810.html#p01
- Wikipedia - CAPTCHA
- http://ja.wikipedia.org/wiki/CAPTCHA
より安全な CAPTCHA とは?
はてなの CAPTCHA が問題視されているわけだが、「では一体どういう CAPTCHA がより安全なのだろう?」
という疑問が当然出てくる。
Breaking CAPTCHAs with NNsによると、
CAPTCHA 破りの工程は,画像から文字を1文字づつ切り出す「分割」 (segmentation) の段階と, 切り出した文字を1文字ごとに解析する「認識」 (recognition) の段階から構成されるが, このうちコンピュータにとって困難なのは「分割」の方であり,「認識」は比較的容易であるとされる。
Kumar らの研究の結果は,文字による視覚 CAPCHA に関して, 文字毎の「認識」を困難にさせることを意図した歪みやノイズには全く意味が無く, そのような労力は文字の「分割」を困難にさせる方へと注がれることが望ましいという結論を導き出している。ということで、「分割」し難い CAPTCHA が安全であるという研究結果が発表されているそうだ。 その研究結果を直接参照してみると、何故「分割」がコンピュータにとって難しいのかが説明されている。
4.1 The segmentation problemより安全な CAPTCHA が具体的にどういうものかというと、同じ論文内では以下の様に提案されている。
As a review, segmentation is difficult for the following reasons:
- Segmentation is computationally expensive. In order to find valid patterns, a recognizer must attempt recognition at many different candidate locations.
- The segmentation function is complex. To segment successfully, the system must learn to identify which patterns are valid among the set of all possible valid and non-valid patterns. This task is intrinsically more difficult than classification because the space of input is considerably larger. Unlike the space of valid patterns, the space of non-valid patterns is typically too vast to sample. This is a problem for many learning algorithms which yield too many false positives when presented non-valid patterns.
- Identifying valid characters among a set of valid and invalid candidates is a combinatorial problem. For example, correctly identifying which 8 characters among 20 candidates (assuming 12 false positives), has a 1 in 125,970 (20 choose 8) chances of success by random guessing.
4.2 Building better/harder HIPsこの方式のより詳細な情報が Building Segmentation Based Humanfriendly Human Interaction Proofs (HIPs) に記載されている。
The idea is that the additional arcs are themselves good candidates for false characters. The previous segmentation attacks would fail on this HIP. Furthermore, simple change of fonts, distortions, or arc types would require extensive work for the attacker to adjust to.
![]()
- Using Machine Learning to Break Visual Human Interaction Proofs (HIPs)
- http://research.microsoft.com/~kumarc/pubs/chellapilla_nips04.pdf
- Building Segmentation Based Humanfriendly Human Interaction Proofs (HIPs)
- http://research.microsoft.com/~kumarc/pubs/chellapilla_hip05.pdf
CAPTCHA の実装(Java)
Wikipedia の CAPTCHA によると、CAPTCHA の Java 実装は結構あるようだ。
- The JCAPTCHA Project
- http://jcaptcha.sourceforge.net/
- The reCAPTCHA Project
- http://www.crt.realtors.org/projects/reCaptcha/
- The simple CAPTCHA Project
- http://simplecaptcha.sourceforge.net/
Oct 26, 2007
[Merlin] J2SE 1.4.2 EOL プロセス開始
J2SE 1.4.2 EOL かい?? 早い! 早いよ!!
J2SE 1.4.2 は Sun のサポート終了 (End of Life, EOL) のプロセスを開始しました。 EOL 移行期間は 2006 年 12 月 11 日から次のバージョンである Java SE 7 の提供開始 (現時点では 2008 年 夏の予定) までです。この掲示をもってユーザの皆様は、 最新リリースである Java SE 6 への移行を開始する必要があります。
![[J2SE 1.4.2 EOL announce]](/blog/entries/Merlin/20071026_01/J2SE1-4-2_EOL.png)
- Sun Develper Network - J2SE 1.4.2
- http://java.sun.com/j2se/1.4.2/ja/
- Java Technology EOL Policy
- http://java.sun.com/products/archive/eol.policy.html
- JPCERT/CC REPORT 2007-10-24 - 今週のひとくちメモ J2SE 1.4.2 のサポート終了
- http://www.jpcert.or.jp/wr/2007/wr074101.html#Memo
Oct 25, 2007
[Misc] NetCommons にチャレンジ
NetCommons とは
NetCommons というのは
このサイトは国立情報学研究所が次世代情報共有基盤システムとして開発したNetCommonsの公式サイトです。
NetCommonsはCMS(Contents Management System)とLMS(Learning Management System) とグループウェアを統合したコミュニティウェアです。NetCommonsによって簡単に構築できるサイトとして、 次のようなものが挙げられます。というものだそうだ。Xoops ベースで構築されているとのこと。 LMS のシステムは今まで触ったことが無かったので試してみた。
- e-ラーニングサイト
- NPOやNGOのためのバーチャルオフィス
- 共同研究・学会活動のポータルサイト兼グループウェア
- オフィス用グループウェア
- ソーシャルネットワークサービス
- NetCommons
- http://www.netcommons.org/
NetCommons のインストール
NetCommons には MySQL, PHP, Apache Web Server が必要。 それだけ揃えてしまえば、後は tar ball を拾ってきてインストーラを実行するだけ。 以下は Debian Etch 環境にインストールしたときのメモ。
環境の準備
MySQL 5, PHP5 をインストール。Apache Web Server は 2.x がインストール済みだったのでそのまま利用。
# apt-get install mysql-server-5.0 php5 php5-mysql libapache2-mod-php5 Reading package lists... Done Building dependency tree... Done # mysql -u root Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 8 Server version: 5.0.32-Debian_7etch1-log Debian etch distribution Type 'help;' or '\h' for help. Type '\c' to clear the buffer. mysql> create database netcommons; Query OK, 1 row affected (0.00 sec) mysql> grant all on netcommons.* to netcommons identified by 'netcommons'; Query OK, 0 rows affected (0.00 sec) mysql> flush privileges; Query OK, 0 rows affected (0.00 sec) mysql> exit Bye # cp /etc/php5/apache2/php.ini /etc/php5/apache2/php.ini.original # vi /etc/php5/apache2/php.ini # diff /etc/php5/apache2/php.ini.original /etc/php5/apache2/php.ini 599c599 < ;extension=mysql.so --- > extension=mysql.so # /etc/init.d/apache2 restart Forcing reload of web server (apache2)... waiting . #
NetCommons の設置
NetCommons をダウンロードしてきて設置。 *.php ファイルが EUC-JP の CRLF になっていたので EUC-JP の LF に変換した。
# wget http://www.netcommons.org/modules/cabinet/downloadnum_add.php? path=%2Fcabinet%2F3%2F%A5%B3%A5%A2%A5%D1%A5%C3%A5%B1%A1%BC%A5%B8%CD% D1%2FNetCommons-1.1.2%2FNetCommons-1.1.2.tar.gz&file_id=1941 [1] 2621 # tar zxvf ./NetCommons-1.1.2.tar.gz ./NetCommons-1.1.2/ ./NetCommons-1.1.2/html/ # cd ./NetCommons-1.1.2 # cp -r ./html ./html.converted # cd ./html # for i in `find . -name '*.php'`; do nkf -Lu -e $i > ../html.converted/$i; done # mv ./NetCommons-1.1.2/html.converted /var/www/netcommons # chmod 777 -R /var/www/netcommons/uploads/ /var/www/netcommons/cache/ /var/www/netcommons/templates_c/ /var/www/netcommons/themes/
NetCommons のインストール
"http://example.com/netcommons/" にアクセスしてインストーラを起動する。
NetCommons インストールの後片付け
インストーラの削除と設定ファイルの権限変更を行う。
# rm -rf /var/www/netcommons/install/ # chmod 444 /var/www/netcommons/mainfile.php #
NetCommons にアクセス
"http://example.com/netcommons/" にアクセスする。
とりあえずインストール時に設定した管理者でログイン。
とりあえずは動いたが、何故か管理室に入ることが出来なかった。
NETCOMMONS_SYSTEM_PATH というグローバル変数(?) がセットされていないのだが・・・。
何故?? (面倒なので調べていないw)
Oct 24, 2007
[WebService] PlaceEngine API にチャレンジ
PlaceEngine とは
PlaceEngine は、Wi-Fi 機器を使って簡単に現在位置を推定してくれるソフトウェア。 以前 Mac OS X にインストールして放置してあったのだけれど、API があるということを知ったので早速試してみた。
- PlaceEngine
- http://www.placeengine.com/
- PlaceEngine 技術資料
- http://www.placeengine.com/doc
- PlaceEngine API ローカルアプリケーションプログラミング
- http://www.placeengine.com/doc/tutl
サンプルコード
サンプルコードは、PlaceEngine API ローカルアプリケーションプログラミングとほとんど同じ。
Mac OS X 版では LocalDB 機能(ローカルに位置情報を記録する機能) は使用できないということなので、PlaceEngine サーバに位置情報を問い合わせるサンプルだけ試してみた。
サンプルアプリを作成するためには、
- ここ から PlaceEngine クライアントをダウンロードし、インストールする。ここでは 2007/10/24 現在最新の o070531 を使用するものとする。
- PlaceEngine を起動する。
- ここで PlaceEngine API アプリケーションキーを取得する。
サンプルを動作させると PlaceEngine がセキュリティ警告ダイアログを表示する。 実行しても安全だと思う場合は YES をクリックする。
![[PlaceEngine warning]](/blog/entries/WebService/20071024_01/PlaceEngine_warning.png)
package jp.in_vitro.codelets; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.net.HttpURLConnection; import java.net.URL; public class Codelet { private static final String KEY = "aNR3HYXx1jzYqw24..."; private static final String URL_RTAGJS = "http://localhost:5448/rtagjs"; private static final String URL_LOC = "http://www.placeengine.com/api/loc"; private final long t; public Codelet() { super(); System.setProperty("http.nonProxyHosts", "localhost"); this.t = System.currentTimeMillis() / 1000; } public Loc getLoc() throws IOException { Rtag rtag = this.getRtag(t); if (rtag.getNumap() > 0) { String locRequest = URL_LOC + "?t=" + this.t + "&rtag=" + rtag.getRtag() + "&appk=" + KEY + "&fmt=json"; StringBuilder locResponse = sendHttpRequest(new URL(locRequest)); return parseLocResponse(locResponse); } return null; } protected Loc parseLocResponse(final StringBuilder response) { Loc location = new Loc(); response.deleteCharAt(0); String responseAsString = new String(response); String param[] = responseAsString.split(","); String param2[] = responseAsString.split("\\{"); if (param.length >= 4 && param2.length >= 2) { location.setLon(param[0]); location.setLat(param[1]); String info[] = param2[1].substring(0, param2[1].length() - 1) .split(","); for (int i = 0; i < info.length; i++) { String tk[] = info[i].split(":"); String name = tk[0].substring(1, tk[0].length() - 1); String value = tk[1]; if ("addr".equals(name)) { location.setAddr(value); } else if ("msg".equals(name)) { location.setMsg(value); } else if ("floor".equals(name)) { location.setFloor(value); } else if ("t".equals(name)) { location.setT(value); } } } return location; } protected void printLoc(final Loc loc) { System.out.println("Longitude(経度) : " + loc.getLon()); System.out.println("Latitude(緯度) : " + loc.getLat()); System.out.println("Address(住所) : " + loc.getAddr()); System.out.println("Floor : " + loc.getFloor()); System.out.println("Message : " + loc.getMsg()); } public Rtag getRtag(final long t) throws IOException { String rtagRequest = URL_RTAGJS + "?t=" + this.t + "&appk=" + KEY; StringBuilder rtagResponse = sendHttpRequest(new URL(rtagRequest)); Rtag rtag = this.parseRtagResponse(rtagResponse); return rtag; } protected Rtag parseRtagResponse(final StringBuilder response) { Rtag rtag = new Rtag(); String splitRtagjsResponse[] = response.substring(9, response.length() - 2).split(", *"); String r = splitRtagjsResponse[0].substring(1, splitRtagjsResponse[0] .length() - 1); int numap = Integer.parseInt(splitRtagjsResponse[1]); String t = splitRtagjsResponse[2]; rtag.setRtag(r); rtag.setNumap(numap); rtag.setT(t); return rtag; } protected StringBuilder sendHttpRequest(final URL url) throws IOException { HttpURLConnection connection = null; BufferedReader reader = null; try { connection = (HttpURLConnection) url.openConnection(); connection.connect(); reader = new BufferedReader(new InputStreamReader(connection .getInputStream(), "UTF-8")); StringBuilder response = new StringBuilder(); String line = null; while ((line = reader.readLine()) != null) { response.append(line); } return response; } finally { try { if (reader != null) { reader.close(); } } finally { if (connection != null) { connection.disconnect(); } } } } public static void main(final String[] args) throws Exception { Codelet me = new Codelet(); Loc loc = me.getLoc(); me.printLoc(loc); } public static class Rtag { private String rtag; private int numap; private String t; public Rtag() { super(); } public String getRtag() { return this.rtag; } public void setRtag(final String rtag) { this.rtag = rtag; } public int getNumap() { return this.numap; } public void setNumap(final int numap) { this.numap = numap; } public String getT() { return this.t; } public void setT(final String t) { this.t = t; } } public static class Loc { private String lat; private String lon; private String addr; private String msg; private String floor; private String t; public Loc() { super(); } public String getLat() { return this.lat; } public void setLat(final String lat) { this.lat = lat; } public String getLon() { return this.lon; } public void setLon(final String lon) { this.lon = lon; } public String getAddr() { return this.addr; } public void setAddr(final String addr) { this.addr = addr; } public String getMsg() { return this.msg; } public void setMsg(final String msg) { this.msg = msg; } public String getFloor() { return this.floor; } public void setFloor(final String floor) { this.floor = floor; } public String getT() { return this.t; } public void setT(final String t) { this.t = t; } } }
サンプルコードの実行結果
Longitude(経度) : 13*.****** Latitude(緯度) : 3*.****** Address(住所) : '東京都************' Floor : null Message : '位置が取得できました'
Oct 23, 2007
[Library] jMock で java.sql.Connection のモックオブジェクト生成にチャレンジ
JMock で java.sql.Connection のモックオブジェクト作成に挑戦してみた。 ・・・と言っても、まだ jMock のサンプルを眺めただけ。
- jMock
- http://www.jmock.org/
サンプルコード - その1
とりあえず基礎の基礎。 単純な java.sql.Connection のモックオブジェクトを作成してみた。 example1 はテスト成功パターン。example2 はテスト失敗パターン。
package jp.in_vitro.codelets.jmock; import java.sql.Connection; import java.sql.SQLException; import java.sql.Statement; import org.jmock.Expectations; import org.jmock.Mockery; public class Codelet { public static void main(String[] args) throws SQLException { Codelet me = new Codelet(); me.example0(); me.example1(); } protected void example0() throws SQLException { Mockery context = new Mockery(); final Connection connection = context.mock(Connection.class); context.checking(new Expectations() { { one(connection).close(); } }); connection.close(); context.assertIsSatisfied(); } protected void example1() throws SQLException { Mockery context = new Mockery(); final Connection connection = context.mock(Connection.class); context.checking(new Expectations() { { one(connection).close(); } }); // connection.close(); context.assertIsSatisfied(); } }
サンプルコード - その2
次に java.sql.Connection から java.sql.Statement を返してみた。 とりあえず指定した java.sql.Statement を java.sql.Connection#createStatement から返すことに成功。
package jp.in_vitro.codelets.jmock; import java.sql.Connection; import java.sql.SQLException; import java.sql.Statement; import org.jmock.Expectations; import org.jmock.Mockery; public class Codelet { public static void main(String[] args) throws SQLException { Codelet me = new Codelet(); me.example2(); } protected void example2() throws SQLException { Mockery context = new Mockery(); final Connection connection = context.mock(Connection.class); final Statement expected = context.mock(Statement.class); context.checking(new Expectations() { { one(connection).createStatement(); will(returnValue(expected)); } }); Statement actual = connection.createStatement(); System.out.println("expected: " + expected + "@" + expected.hashCode()); System.out.println("actual: " + actual + "@" + actual.hashCode()); context.assertIsSatisfied(); } }
Oct 22, 2007
[Misc] 各社携帯の XHTML 対応状況メモ
NTT Docomo, AU, Softbank mobile の XHTML 対応状況を調べたのでメモ。
NTT Docomo
「端末スペック一覧」ページに XHTML の対応状況が記載されている。
- XHTML Basic 1.1
- http://www.w3.org/TR/xhtml-basic/
- 作ろう i モードコンテンツ
- http://www.nttdocomo.co.jp/service/imode/make/
- 端末スペック一覧
- http://www.nttdocomo.co.jp/service/imode/make/content/spec/index.html
- iモード対応XHTMLの考え方
- http://www.nttdocomo.co.jp/service/imode/make/content/xhtml/outline/s1.html
AU
「XHTML 対応機種」ページによると
「XHTML」で表記されたコンテンツを、作成者の意図どおりのデザインで閲覧するには、WAP2.0ブラウザ搭載端末で表示する必要があります。HDMLブラウザ搭載端末では、HDML標準対応となり、「XHTML」コンテンツに関しては、EZサーバによるコンテンツ変換機能を使用し「XHTML → HDML」の変換を行って表示することになります。ということだそうだ。WAP2.0ブラウザ搭載状況は「機種別情報一覧」ページに記載されている。
- 技術情報
- http://www.au.kddi.com/ezfactory/tec/index.html
- XHTML 対応機種
- http://www.au.kddi.com/ezfactory/howtoxhtml/02.html
- 機種別情報一覧
- http://www.au.kddi.com/ezfactory/tec/spec/new_win/ezkishu.html
Softbank mobile
「ウェブ技術資料 - 概要編」によると
1.2 サービス世代だそうだ。3G サービス対応端末、WAP/MMS サービス対応端末で表示可能ということのようだ。 ・・・残念なことに、3G サービス対応端末、WAP/MMS サービス対応端末の情報は見当たらなかった。
以降、回線交換のみに対応する端末を C 型端末と呼称し、パケット交換サービス(PDC-P)にも対応する端末を P 型端末と呼称し、3G サービスに対応する端末を W 型端末、WAP/MMS サービスに対応する端末を 3GC 型端末と呼称する。
1.3.1. ウェブ
・コンテンツは HTML(Hyper Text Markup Language) もしくは MML(Mobile Markup Language), XHTML で記述する。ただし、MML は C 型および P 型端末でのみ利用可能であり、 XHTML は W 型、3GC 型端末でのみ利用可能である。
- Softbank Developers Support Site
- http://developers.softbankmobile.co.jp/dp/
- ウェブ技術資料 - 概要編
- http://www2.developers.softbankmobile.co.jp/dp/tool_dl/download.php?docid=110&companyid=
- ウェブ技術資料 - XHTML 編
- http://www2.developers.softbankmobile.co.jp/dp/tool_dl/download.php?docid=135&companyid=
- 端末情報
- http://developers.softbankmobile.co.jp/dp/tech_svc/info/
Oct 16, 2007
[Apple] Pathway メモ
Pathway は Wikipedia ビューア。
Wikipedia の関連付けられたエントリからエントリへ渡り歩きながら必要な知識を得ることができる。
これは便利。
Pathway is an app designed to solve the aforementioned problems. Its aim is to help you discover Wikipedia without having to worry whether you’ll have enough time to read everything you want, or if you’ll get lost.
It accomplishes this by presenting you with a graphical “network” representation of your visited article pages. A node represents an article, a connection between two nodes means, of course, that you’ve gone from the first article to the second one. You can save the network you’ve created to disk and recover it.
- Pathway
- http://pathway.screenager.be/
- About Pathway
- http://pathway.screenager.be/about-pathway/
Oct 14, 2007
[Apple] Shrook メモ
Shrook は Mac OS X 用の RSS Reader。
しばらく Vienna を使用していたのだが、唐突に Feed の読み込みをしてくれなくなった。
どうも過去のエントリデータが破損した模様。
機能的には満足していたのだが、どうも動作がもっさりしていたこともあり Shrook を試してみることにした。
さて、データ量が増えてきたときにどうなることやら・・・。
Oct 13, 2007
[Misc] SSL 証明書のインストール時に X509_check_private_key:key values mismatch エラー
Apache Web Server 2.2.6 に SSL 証明書をインストールしたときに不思議なエラーに遭遇した。
何のことはない、間違って別サーバの SSL 証明書を使っていただけだった(^^;[warn] RSA server certificate CommonName (CN) `hoge.example.com' does NOT match server name!? [error] Unable to configure RSA server private key [error] SSL Library Error: 185073780 error:0B080074:x509 certificate routines:X509_check_private_key:key values mismatch
で SSL 証明書の内容を確認したら別サーバのものであることが一瞬で判明。 正しい SSL 証明書を持ってきたらすぐに解決。やれやれ。# openssl x509 -noout -text -in ./server.crt
Oct 10, 2007
[Apple] ImageMagick を Mac OS X にインストール
ImageMagick を Mac OS X にインストールした際のメモ。 メモと言っても、MacPorts を使っているので大したことはやっていない。
- ImageMagick: Convert, Edit, and Compose Images
- http://www.imagemagick.org/
MacPorts を使って ImageMagick をインストール
$ sudo port install ImageMagick
[Apple] ImageMagick を Mac OS X にインストール
ImageMagick を Mac OS X にインストールした際のメモ。 メモと言っても、MacPorts を使っているので大したことはやっていない。
- ImageMagick: Convert, Edit, and Compose Images
- http://www.imagemagick.org/
MacPorts を使って ImageMagick をインストール
$ sudo port install ImageMagick
Oct 09, 2007
[Apple] MacPorts を Mac OS X にインストール
MacPorts を Mac OS X にインストールした際のメモ。
- MacPorts
- http://www.macports.org/
MacPorts のインストール
- MacPorts のサイトから dmg ファイルを拾ってくる。
- dmg をマウントし、インストーラを実行。後はウィザードの指示通り。
-
/Users/me/.bashrc を編集。以下を追加する。
export PATH=/opt/local/bin:/opt/local/sbin/:$PATH export MANPATH=/opt/local/man:$MANPATH
-
MacPorts の初期設定。
$ sudo port -d selfupdate $ sudo port -d sync