2008年01月28日
GIS-GW等で通信経路での詐称を検証する方法
方々よりノウハウを記事にして共有してくれと突かれていたので、遅くなりましたが記事化します。
その前に1つだけエクスキューズしておくと、小山さんの記事あたりで
位置詐称を許さないここギコねねさん
とか書かれてますけど、別に許さないつもりはなくて...確かにGeoPlatFormAPIのような位置取得APIや、GIS-GWのような位置流通APIの双方で詐称を検証する方法とか事ある毎に口にしてるんですけども、これは「何が何でも詐称を許さない」からそうしてるわけではなくて、それぞれ理由(それも異なる理由)がありまして、
- 位置取得APIについては、社内用に作っている方がメイン用途をエンタテイメント分野としているので、そちらでは否が応でも「詐称は許さないようにせざるを得ない」のですね。
だから自分の方はこだわってるだけで、別にそういう用途に使う事を想定していないのであれば、たとえば携帯から位置を取って地図を表示するだけのサイトに詐称対策が必要とも思えないし、詐称対策してないとAPIとして無意味、などという事は全くありません。
その意味では、GeoPlatFormAPIを紹介した記事で、「が、ちょっと甘い」等と、詐称対策がされてないとダメという印象の表現をしてしまったのは、全く適切ではありませんでした...スンマセン。 - GIS-GWの方は、私がこだわっているというよりも、GIS-GWメンバによってGIS-GW上に期待されていることの方が、詐称対策を必要としている、というのが個人的印象です。
全くの個人的には、ケータイ位置情報サイト間で情報を流通する際に、それほど詐称対策が必要とは思えない(他のサイトで取った位置情報をGETで流されてきて、それを元にエリアを盗った!等と認めるようなエンタメサイトも考えにくいし。まあ、将来的に位置情報のGET持ち回りでなくブロードキャスト等が実現されたら話は別なのですが)し、サイト間で流通させたい位置情報としては、単にケータイデバイスで直接取得したもんだけではなく、地図で微修正したりしたもんも含まれるだろうから、そこに詐称対策を盛り込む必要はほとんど感じていなくて、別に経緯度をGETにつけて流すだけの緩いもんでいいんじゃないの?と思ってたんだけど。
そしたら、他のGIS-GWのメンバの方から、位置情報の信頼度も流通したいよね(たとえば、doodleは本当にその場にいる人しか発言させないらしいので)、果てはユーザのユーザID情報までパラメータとして引き渡したいよね、みたいなGIS-GWへの要望が挙がってきた。
そこまで情報を保証したり、センシティブな情報を流そうと思ってるなら、詐称対策せずにGETでただ流してたら相当やばいよね、ということで「詐称対策しなきゃ」とこだわっているわけでして、個人的信念よりは他者要望に基づいて必要性を主張しているような感じです。
まあ、どう言ったところで位置情報詐称検証法にこだわっていることは事実なのですが、別にいろんなユースケースがあるにも関わらず、その必要性も考慮せずに脳みそ筋肉的に、「位置情報詐称を考慮していない位置APIなんてクソだよクソ」的なことをここギコは考えている、と思われるのも嫌なので、一応エクスキューズをば。
で、本題。
位置情報詐称検出といっても、別に難しいことをかんがえているわけではなくて、ほんまにはてな認証APIやLivedoor認証API、Wassr認証APIなんかの発送パクってるだけ。
要するに、ユーザのID情報と1対1で紐付いた秘密鍵を発行して、その秘密鍵をベースに詐称検出用のシグニチャをデータに付加してやるだけのこと。
例えば、GIS-GWのインタフェースの現状仕様は、Serendi(ID:SE)からdoodle(ID:DO)に対し、経緯度と取得時間の情報を送ってやろうとすれば、SerendiからGIS-GWへの遷移は
http://ja.gisgw.com/gw?s=SE&d=DO&lat=35.8264&lon=139.6920&t=20070828120413
みたいなURLになるわけだけど、これを詐称検証可能にしてやろうと思えば、上記の赤の部分全体を、Serendi/GIS-GW間で共有している秘密鍵を使ってHMAC_SHA1ダイジェストを取ってやった値を、クエリ末尾に付加してやればよい。
http://ja.gisgw.com/gw?s=SE&d=DO&lat=35.8264&lon=139.6920&t=20070828120413&sig={赤字部分のSerendi秘密鍵でのhmac sha1 hexdigest}
みたいにすればよいだけ。
これを受け取った側でも、同様に秘密鍵を使い赤部分のダイジェストを取ってやって、一致していれば詐称なし、一致していなければ詐称あり、という感じにすればよい。
GIS-GWは上記を受け取った場合、doodleに位置情報を転送するわけだけど、これについても同様にシグニチャを付加すればよい。
ただし、今度は使う秘密鍵が、doodle/GIS-GW間で共有している秘密鍵になる点だけが異なる。
http://doodle.st/gw?s=SE&d=DO&lat=35.8264&lon=139.6920&t=20070828120413&sig={赤字部分のdoodle秘密鍵でのhmac sha1 hexdigest}
みたいな感じ。
実際問題これだけの話で、そんなたいした話ではない。
基本、位置流通APIだけでなく、位置取得APIでも、ほぼ同じやり方で詐称検出はできる。
けど、まあこちらでも作ってていくつかのベストプラクティス?的なのもあるので、それを補足しておくと、
- 赤字で書いた部分のデータ文字列のシグニチャをとる場合だけど、上記の例だと全部ASCIIデータなので問題ないけど、マルチバイトデータ等URLエスケープ対象文字が混ざる場合、URLエスケープ後のデータでシグニチャを取ると、URLエスケープの微妙な揺らぎ(スペースは+にするのが常道と思いますが、%20にされる場合も少なくない、等)のためにシグニチャがずれてしまうことがありそう。
シグニチャを取る際のデータはURLエスケープ前のバイナリデータとするのが吉かなと思う。 - 本仕様で検出できるのは、URL上のデータに詐称がないかだけ。
例えば、上記URLでlat=35.8264がlat=34.8264に変更されれば検出できるけれど、「シグニチャまで含めたこのURLセット」を、別のユーザに転送されたり、或いは別の日時に再利用されたりといったことは検出できない。
よって、そういった部分までケアしようと思えば、シグニチャを取る対象のデータの中に、時刻依存やユーザ依存のデータ(ユーザIDとか、ユーザIDをGETで流すのがやばければUAとか?)を埋め込んでおき、URLの詐称検証とは別に、時刻妥当性やユーザ妥当性を判断する必要がある。 - 位置詐称対策シグニチャを埋め込んでいるデータに対し、下流でシグニチャを外すのは問題ないけど、対策のされていない元データに対して、下流でシグニチャを埋め込むのは絶対ダメ。
たとえば上の例で、doodleは詐称対策されたデータを望んでいるからといって、Serendi→GIS-GW間は無検証で送られてきたデータに対し、GIS-GW→doodle間にシグニチャを埋め込むのはやってはいけない。
でないといくらGIS-GW→doodle間は検証できても、その上のSerendi→GIS-GW間でいくらでも詐称できてしまうので、何を信用していいのか判らなくなる。
みたいなところでしょうか。
でも、これは飽くまで詐称を検出できるかどうかの話なので、通信路の秘密みたいな話になるとまた別の話、というかGETでできるの?みたいな感じになる。
GIS-GWとしてはできればあまり重い仕様にしたくない、GET程度の軽い仕様がいいということなので、それでできる範囲は範囲のライトな仕様でおいておくとして、でも一方でユーザID情報みたいなのも流したいという要望もあるので、そうなるとGETなんかで流して本当にいいのかな?みたいな感じもしてる。
そのレベルになってくると、超重くなってくるけど先日アイデンティティ飲み会で知ったSAMLを応用するとか、そういうレベルの話になるんじゃないか、という感じがしている。
![[ここギコ!]](http://kokogiko.net/logo.png)



・国連人権委、アイヌ・琉球文化の保護を日本に勧告(ほるほる)
・GoogleMapsと連動したいならPostGISの他にmysqlという選択肢も出てきた あとジオメディアサミット関西も(okumula)
・人員がクラスタ化できている職場と言うのはうらやましい そろそろ限界です(「ま」のつく人)
・もうAmazonクレジットカードは使いません...楽天カード一本で。(名無し)
・ジオメディア忘年会 新年会から始まり東京1、2、関西と続いたジオメディア2008の締めくくり(ぴかぴか)
・GoogleMapsと連動したいならPostGISの他にmysqlという選択肢も出てきた あとジオメディアサミット関西も(kokogiko)
・GoogleMapsと連動したいならPostGISの他にmysqlという選択肢も出てきた あとジオメディアサミット関西も(かやま)
・なんか天から2兆円降ってくるらしいので みんな思い思いのところに募金なり寄付するのはどうか(大阪府民)
・なんか天から2兆円降ってくるらしいので みんな思い思いのところに募金なり寄付するのはどうか(kokogiko)