質問: お世話になります。 monacaを用いて、HTML5 + Javascriptベースでのスマートフォン用evernoteアプリ開発に取り組んでおります。 evernoteのサーバーとやり取りするためには、キー(consumerKey, consumerSecret)を使い、OAuth認証する必要があります。 evernoteウェブページ()を参考に開発をしていますが、このページのサンプルコードでは、consumerKey, consumerSecretを「直接」ソースに記載しています。 原理上、ソースに consumerKey, consumerSecret を直接記載せざるを得ず、特にjavascriptでは、原理上、ソースの暗号化もなされませんので(多少の難読化はあるかもしれませんが)、アプリを公開したら、例えばandroidならapkファイルを覗くだけで簡単にconsumerKey, consumerSecret が取得できてしまうのではないかと思います。 これらが、簡単に流出しないように、うまくソースを書く書き方はあるでしょうか。 直感的には、これらからハッシュを生成してやり取りできれば、とも思うのですが、evernoteのoauth認証部分が難読化されていて、(私にとっては)ブラックボックスで手の施しようがない状況です。 そもそも、これらのキー(consumerKey, consumerSecret)は、流出してしまっても良いものなのでしょうか。 Evernote社が流出前提でリスクマネジメントをしていればよいとも思うのですが、直感的にはアプリのなりすましができてしまうので、やはり良くないでしょうか。 可能なら、お知恵をお貸しいただけないでしょうか。 よろしくお願い申し上げます。
回答: JavaScript SDKを使って、Webブラウザから「何らかのServerに頼らず」直接APIを叩きたい、という話であれば、APIのClientとなるアプリがどれだけコードが見られてしまう可能性が高いか、という観点になると思います。Client IDとClient Secretがばれてしまえばクライアント詐称もできるよね、という指摘は正しいです。EvernoteのQuick Startを見るとCordovaを使った例だったので、Serverの存在なくAndroid/iOSアプリから直接Evernote APIを使うという話になりますね。そうなると、おっしゃる通り「そのアプリがどれだけコード見られちゃうか問題」が勃発します。そして、それを完全に隠すことは無理なので「できるだけ読まれないようにしようね」という努力をどれだけするか、が一般的な対処法だと思います。 今すぐできることと言えば・・・ * Objective C, Javaのコードの難読化をとにかく頑張る。そっちにClient ID, Secretを書いておいて、JavaScript側には書かない。 * C, C++側に書いて、さらに難読化する。 * 単に文字列リテラルだとみられる可能性大なのでコードロジックとしてうまく隠す。 が思いつきます。ただし、これらは根本的な解決策ではない、という点が重要です。 OAuth2の世界だと、こういった「秘密なものを隠せないクライアント向け」にImplicit Grant Flowがあったりしますが、EvernoteがそれではなくClient Secretの適用を前提としているあたり、あまりスマホアプリでAPI使う場合のSecurityへの意識は高くなさそうだな、というのが個人的な見解ですね。 この話は「クライアント詐称されちゃうじゃん!危険だ!」とすぐに考えてしまうのではなく、ではClient ID, Client Secretが漏れた際にどんな悪いことが起きるのか?を想像してリスク判断する必要があります。例えば、 * APIを使うことは無償で可能。 * ユーザ認可がないとAPIは使えない。 * 誰でも自由にClient ID, Client Secretを入手可能。 という場合であれば、そんなに気にしなくても良いのかな、と個人的には思います。もちろん、クライアント認証のみで使えるAPIがあれば、話は別ですが。あとはクライアント詐称は「あなたの個人名、企業名を語ったアプリの登場」を意味することになりますが、例えばユーザに「正しいアプリはこれですよ」と偽物アプリかどうかを判断できる別の仕組みを提供して警告する、という手もあるかと。 この辺のリスク判断はアプリ開発者、アプリ提供者にゆだねられているものだったりするので、もちろんできるだけ漏れないよう努力しておくことは必要かと思いますが、完璧に隠さないとアプリを公開できないと考えるかどうかは、漏れたときの被害として何があるかを検討してご判断いただければ良いかと思います。