2010年11月28日日曜日

HMAC方式で認証用のハッシュを生成するメモ


HMAC
(Keyed-Hashing for Message Authentication Code)とは?

HMACはハッシュ(Message Digest)生成アルゴリズムで、MD5やSHA1、SHA2等と組み合わせて使う。(それぞれ「HMAC-MD5」「HMAC-SHA1」などと呼ばれる。)



なぜ認証用のハッシュがHMACでなければいけないのか?

HMACでないハッシュ関数を認証用のハッシュ(トークン)生成に使うと、秘密鍵を知らなくても任意のハッシュを生成できるケースがあるらしい。(参考:Kazuho@Cybozu Labs: Re: はてな認証 API

よく理解していないけど、ハッシュアルゴリズムがデータブロック単位で処理することに起因している?
暗号化においてCBCでIVが固定の場合と同じような問題?(参考:floatingdays: PHPで AES方式 (Rijndael-128)で暗号化するメモ

それに対してHMACでは、変換元の値とは別に指定する秘密鍵組み合わせることにより、上記の問題を回避しているらしい。(参考:HMAC: Keyed-Hashing for Message Authentication



HMAC方式でハッシュを生成する方法

今どきのプログラム環境は言語レベルで実装してるみたい。

PHP 5.1.2以降の場合
HMAC 方式を使用してハッシュ値を生成する - PHP 5.3 日本語マニュアル

PHP 5.1.1以前の場合、外部ライブラリとしてmhashが必要 (参考:導入 - PHP 5.3 日本語マニュアル
ハッシュ値を計算する - PHP 5.3 日本語マニュアル

Javaの場合
試験管のなかのコード :: JDK 1.4.x 環境で HMAC with the SHA256 を使用する方法



参考:

2010年11月21日日曜日

PHPで 「Webページの有効期限が切れてます」となる時の傾向と対策

PHPでフォーム等を作った場合、Webブラウザの戻るボタンやJavaScriptのhistory.back()で前のページに戻った時に「Webページの有効期限が切れてます」と表示されることがある。

上記はIEの場合で、ブラウザによって少し挙動が違う(下記)。
いずれもページを更新(リロード)するとサーバにPOSTが再送信され、ページが表示される。
  • IE
    • 上記(IE8の例)のような画面が表示される。
  • Firefox
    • 「このページを表示するにはフォームデータを再度送信する必要があります。フォームデータを再送信すると以前実行した検索、投稿や注文などの処理が繰り返されます。」という確認ダイアログが表示され、「再送信」ボタンと「キャンセル」ボタンが表示される。「再送信ボタン」をクリックするとページが表示される。
  • Chrome
    • 「フォーム再送信の確認
      このウェブページを正しく表示するには、先ほど入力したデータが必要です。データをもう一度送信することは可能ですが、このページで行った操作をすべて繰り返すことになります。データを再送信してこのページを表示する場合は [再読み込み] をクリックしてください。」というメッセージのみの画面が表示される。
  • Safari
    • このようなダイアログが表示される。(Windows版で確認。Mac版は分からない。)



犯人はだれだ?


原因は、PHPでSESSIONを使うと(デフォルト設定では)自動でキャッシュ制御用のHTTPヘッダーが送出され、それによりクライアント側のキャッシュが使用不可にされるため。(参考:floatingdays: PHPでブラウザキャッシュを有効にする

つまり、下記条件を全て満たした場合にこの現象が発生する。
  1. HTTP POSTで遷移してきた。
  2. SESSIONを使っている。(session_start()してるか、php.ini等でsession.auto_start=1に設定している。)
  3. 次のページに行ってから、ブラウザの履歴機能(JavaScriptのhistory.back()を含む)で戻ってきた。



じゃあどうすればいいの?

対策として有名なのは、session_start()する前に、session_cache_limiter('none')とすること。
session_cache_limiter('none');
session_start();
これにより、SESSIONを使っても余計なHTTPヘッダーが送出されなくなる。

または、php.ini等でsession.cache_limiterに"none"を設定しても同じことになる。(おそらく元ネタはこのあたりだろう → PHP: session_cache_limiter - Manual

実際にこれで問題は解決する。



異論反論オブジェクション! [shut very bad!]

しかし、「PHP/「ページの有効期限切れ」対策 - Glamenv-Septzen.net」によると、これはPHPが想定しているパラメータではなく、お行儀のよいやり方ではないらしい。

'none'というパラメータは正しいパラメータではなく、それゆえに何もHTTPヘッダーを送出しないという挙動になるらしい。
(ただし、もし「規定外のパラメータはスルーする」というのが意図した仕様だとしたら、'none'でも何でも「正しいパラメータ」だけど。)

上記の記事ではsession_cache_limiter('none')ではなくsession_cache_limiter('private_no_expire')を推奨している。
「ページの有効期限切れ」をsession_cache_limiter()で解決 - shinyanakaoのよすがブログ」でも同様にprivate_no_expireを推奨している。

しかし、実際にsession_cache_limiter('private_no_expire')を使うと、やはり余分なHTTPヘッダーが送出される。

private_no_expireの場合、(privateに比べて)Expiresが送出されなくなるが、「Cache-Control: max-age=(session.cache_expire ぶんだけ未来)」が送出されるため、やはりブラウザに影響が出てしまう。(参考:現在のキャッシュリミッタを取得または設定する - PHP 5.3 日本語マニュアル
Firefoxでは問題ないが、IEだとリロード時にもキャッシュを使ってしまい、サーバからのリロードができなくなるようだ。(参考:Webアプリケーション開発ラボ by NPO情報活用センター - PHP:キャッシュ問題について。PHP Tips|ワークスポット・ジェーピー
おそらくsession.cache_expireで設定されている期間はキャッシュが有効になるのだろう。(Expiresでそう指定しているのだから、IEは悪くない。)

なので、お行儀が悪くてもsession_cache_limiter('none')を使うしかないのでは?('none'じゃなくて'hoge'でも'hage'でも「正しい」パラメータ以外なら何でもいいけど。)



新たな選択肢

しかし、こういう手もあるよ。
session_start();
header('Expires:'); //下記「余談」の追記も参照
header('Cache-Control:');
header('Pragma:');

header()でセミコロンの右に何も書かないと、PHPは何も送出しないようだ。
これにより、session_start()のHTTPヘッダー送出を上書きし、結果的に何も送出しない。

session_cache_limiter('none')より冗長だが、明示的という意味ではいいかもしれないと思っている。
(キャッシュを有効にしたい場合にも応用が効く。)



余談

上記のようにブラウザキャッシュの無効化を無効化すると、当然ながらSESSIONの最新情報が反映されていないブラウザキャッシュをブラウザが表示してしまうので注意。

(2011/1/7 追記)
IEはキャッシュがあり、かつ、そのキャッシュがExpiresを何も指定されていないと、アドレスバーにURLを直接入力された場合やリダイレクトした場合などにサーバにアクセスせずにキャッシュの方を使ってしまう。(Firefoxはその場合もサーバにアクセスしてくれる。)
ブラウザの履歴機能を使うためにキャッシュはさせたいが、上記の場合にはサーバにアクセスさせたい場合は、Expiresで-1を指定すると良いようだ。
header('Expires: -1');
ログイン管理をする場合などはこれをやっておいた方が良さそう。
(追記終わり)

また、POSTのパラメータに「チケット」(=ワンタイムトークン)を入れることによる二重POST防止を推奨するのは正しい。というか二重POSTを確実に防ぎたいと思ったらこれしかない。


2010年11月16日火曜日

大手サイトがやっている自サイト専用のURL短縮サービス

思いつくものをまとめてみた。
bit.lyによる独自ドメインURL短縮サービスで日本人にあまり馴染みのないもの(NY Timesとか)は除外した。

サイト
短縮URL
備考
Google Maps
FeedBurner
goo.gl
Google Mapsは goo.gl/maps/xxxx
FeedBurnerは goo.gl/fb/xxxx
その他のサイトの場合、 goo.gl/xxxx
YouTube
youtu.be
後ろに動画のIDを付けると、その動画の短縮URLになる。
例: http://youtu.be/4qCbiCxBd2M
Yahoo!
yhoo.it
powered by bit.ly
uk.yahoo.comやfr.yahoo.comは短縮してくれるが、
yahoo.co.jpは対象外。なぜかtw.yahoo.comも対象外。
Flickr
flic.kr

Delicious
icio.us
ドメインハックの先駆者がこんな形で再利用されるとは。
Bing
binged.it
短縮URLは既に機能しているが、
URL生成はまだプライベートBeta。
Amazon
(USのみ)
amzn.com
後ろにASINを付けると、その商品ページの短縮URLになる。
例: http://amzn.com/B002FQJT3Q
Kindleの場合、「amzn.com/k/xxx」のようだ。
アソシエイトはできるのかな?
Amazon
amzn.to
powered by bit.ly
こちらはamazon.co.jpも対象。
Facebook
fb.me

Twitter
t.co

foursquare
4sq.com

MySpace
mysp.ac
powered by bit.ly
Ustream
ustre.am

Dailymotion
dai.ly
powered by bit.ly
Scribd
scr.bi
powered by bit.ly
楽天
r10.to
どこで生成できるか分からなかった
mixi
mixi.at

ニコニコ動画
nico.ms

はてなブックマーク
htn.to
powered by bit.ly (2011/3/21 訂正)
PIXIV
p.tl

日経新聞
s.nikkei.com
powered by bit.ly


日経新聞のサブドメインを使うやり方は好感が持てる。
Bingはよく考えたら自サイト専用じゃないけどまあいいや。
ところでyhoo.itはYahoo! Italia(it.yahoo.com)と間違えそう。


(2011/3/21 追記)
htn.toは、はてなブックマークだけでなく、はてな全般で使われているみたい。(これを書いた後で変わった?)
また、bit.ly proを使ってるわけではないようだ。
(追記終わり)


参考:
Bit.ly、月間47億クリック。Pro版も好調、Yahoo、MySpaceらも採用
bit.ly | Basic | a simple URL shortener
JSTwi


2010年11月10日水曜日

Microsoftの Webページ埋め込み用画像拡大ビューワーサービス Zoom.it

Zoom.itはMicrosoftのLive Labsが作ったWebページに埋め込める画像Viewer。
もともとはSeadragonという名前だったようだ。(参考:巨大な画像のビューアーを作ってくれる『Seadragon』 - 100SHIKI

画像のURLを指定すると、その画像をZoom.it側で取り込んで、表示できるようになる。
Zoom.it側で取り込むので、見るときはZoom.itの発行するURLで見るか、埋め込み用のJavaScriptを自分のサイトに埋め込んで見る。

画像のファイルサイズは無制限のようだ。(参考:Zoom.it - FAQ
Web公開用画像の外部ストレージサービスとしても使えるのかな...!

そしてこれ、画像だけでなく、実はWebページのキャプチャもしてくれる。URLとして、画像のURLの代わりにWebページのURLを入力するだけ。
UTF-8のページなら日本語でも問題なくキャプチャできた。(Shift_JISの場合は文字化けした。)

注意点としては、一度Zoom.itに取り込ませた画像は削除も変更もできない。「あなたがそのURLを公開しない限りは見つかることはないから大丈夫だよ」(Zoom.it - FAQ)と言われても、公開してしまったら後で困るかもしれないので慎重に?

これを作ったMicrosoftのLive LabsはBing部門に吸収された(参考:Microsoft Live Labs)ようだが、今後Zoom.itはどうしていくつもりなんだろう?
FlickrのようなCGMとして展開していかないのかな。


ところでZoom.itはGoogle Analyticsが仕込んである。MSも自前でアクセス統計を持ってなかったっけ?

2010年11月9日火曜日

あなたの知らないbit.lyの便利機能

URL短縮サービス最大手のbit.ly。Yahooなど大手サイトの短縮も請け負ってもはやURL短縮サービスの代名詞になりつつある。
そんなbit.lyだが、URL短縮以外のサービスもやっていることについては意外と知らないのではないだろうか?


1. 後ろにプラスでクリック数やTwitterでのつぶやきを表示


短縮URLの後ろに"+"(プラス)を付けると、その短縮URLのアクセス統計が見られるのは有名。

でもTwitterでのつぶやき(最大99件)等も見られるようになっているのは知らなかった。
Twitterのつぶやきには、bit.lyで短縮されたものだけでなく、goo.glやTinyURLで短縮されたリンクも含まれて表示されている。BackTweetsから引っ張ってきているようだ。
URLがトップレベル等の場合、その配下の短縮URLも含めたTweetが表示される。(BackTweetsを使うからそうなるんだろう。)
下記の例は「はてなブックマーク」のトップページの短縮URLの統計ページだが、はてなブックマークのトップページだけだなく、はてなブックマーク内の全ての短縮URLのTweetが表示対象となっている。
例: bit.ly statistics for (はてなブックマーク)

また、クリック数はj.mpと共有しているようだ。→ http://j.mp/DeWI+

ちなみに、amzn.toなどのbit.lyの専用短縮URLの場合、プラスを付けるとbit.lyのページにリダイレクトされて統計が見られる。
例: http://amzn.to/CB7N+



2. QRコード

goo.glでは短縮URLの後ろに".qr"を付けるとQRコードが表示されるが、bit.lyもいつの間にか(?)実装していた。
bit.lyの場合、短縮URLの後ろに".qrcode"を付けるとQRコードが表示される。
例: http://j.mp/DeWI.qrcode

goo.glのQRコードより大きい。(goo.glには負けないという意気込みを感じる?)

QRコードは(株)デンソーウェーブの登録商標です。



3. 人気の動画を一覧表示

統計から人気の動画を選び、一覧表示しているようだ。 → bitly.tv | What the world is watching now



4. a.ly

http://a.ly にアクセスするとbit.lyにリダイレクトされる。
しかし残念ながら(?)このa.lyは短縮URLには使えないようだ。

mod_pagespeedとは

Google製のApacheモジュール。インストールするだけでWebサイトを高速化できる。
Apache2.2向けに、CentOS用とUbuntu用が用意されている → Page Speed Downloads


以下は参考ページのリンク。

概要
Google、Apache モジュール「mod_pagespeed」をリリース - スラッシュドット・ジャパン
mod_pagespeed所感 - 最高のコンピューティング環境とは?


具体的な使用例
mod_pagespeed をちょっとだけ試してみた - 酒日記 はてな支店
mod_pagespeedをEC-CUBEを使って早速試してみる - なげっぱなし日誌
紀子さん@へぼぷろぐらまの日常 mod_pagespeedいれてみた。
mod_pagespeedを入れてみた - でぶろぐ


詳しい解説
続・mod_pagespeedの各Filterと設定について ハブろぐ - havelog.ayumusato.com
mod_pagespeedについての考察とか | Yet Another Geek Blog(日々の葛藤日記 Ver.2)


インストール
さくらのVPSにGoogleのmod_pagespeed入れてみた ハブろぐ - havelog.ayumusato.com


感想
けっこうドラスティックに変えちゃうみたい。
JavaScriptはMinifyするらしいけど、IE用の条件付きコンパイルは残してくれるのかな?
「Elide Attributes」がHTML5には対応してるかは要確認。
既存のサイトへのいきなりの適用は危険そう。新しいサイトなら開発段階からこれを使って作ってくのはありかも。
WordPressやRailsなどの代表的なCMSやFrameworkで「使えた」という報告が上がってくれば普及するかも?
Google App Engineでも同じようなことやればいいのに?(オプションとして提供するとか。)

ブログ アーカイブ

tags