QA@IT

SSLサーバ証明書を使わない暗号化通信について

9218 PV

SSLサーバ証明書を使わないで通信内容を暗号化できる仕組みとして
『SHTTP』 というものを考えてみたのですが、
これは十分に "Secure"なものになっているでしょうか?

GitHubにソースコードと概要イメージを掲載しています。

GitHub https://github.com/sklab/SHTTP/

デモサイトhttp://shttp-eu.herokuapp.com/sample/

 

概要

「HTTPS」と対峙した「S-HTTP」プロトコルに似た考えのものですが、
HTTP通信の最初のアクセスの際に別のHTTPSサイトに共通鍵の受け渡しを仲介してもらい、
受け渡し後はアプリケーション層で共通鍵を使ってやり取りするイメージです。

なぜこんなものを?と思われるかもしれないので簡単に作成した背景を説明します。

暗号化した通信を実現するためにはHTTPSを用いれば簡単ですが、
正式なSSLサーバ証明書を取得するための費用が結構な負担になります。

自己署名の証明書を用意してHTTPS通信を行う方法もありますが、
ブラウザ上で警告表示が出ますし、独自ドメインを用いてレンタルサーバーで
運用している場合には自己署名の証明書が使えないこともあります。

SHTTP は個人事業や零細企業、スタートアップビジネスのために
PHPとJavaScriptを使ってAESを使った共通鍵暗号方式の通信を
手軽に行うために作成しました。

共通鍵の受け渡しを仲介するサーバは用意しているため
Sampleのファイルを見てshttp.phpとshttp.jsファイルを組み込むだけで
暗号化した通信を行えるようにしているつもりですが、
この中に脆弱な部分がないか、皆様からのご意見を伺いたいと思い質問させていただきました。

仕組みとして安全かどうかだけに関わらず、
その他の部分で良くない部分があればご教示いただきたいと思っています。

  • 簡潔にいうとただの拡張HTMLエスケープです。 -

回答

低価格SSL(RapidSSL)ならサーバー料金に混ぜても年間1万円で収まります。
共用SSLなら1200円程度で収まります。


ちなみにぱっとみの脆弱性(結構やばい?)

  • 暗号化処理をJSを用いて作成しているのでだれにでもみれる。

HTMLソースを暗号化してもメモリ上に展開されるHTMLソースは復号されています。


追記

暗号化方式ではなく暗号化処理が見えてるのがやばいってことですよ。
あと _1234_ というパスワードを入力した場合 1234 に復号されてますので想定しているパスワードの強度が落ちてしまいます。

必須チェック時に トリムした場合0文字か判定するのはいいですが
入力内容を変更するのは危ないと思います。

_1234_
1234_
_1234
__1234_
_1234__
__1234 __

etc ...
_ は半角スペースとして受け取ってください。

これがすべて同じパスワード等として認識されます。

編集 履歴 (1)
  • 無知で申し訳ないのですが、暗号化処理の内容が見られてしまうのは危険でしょうか?
    アルゴリズム自体は公開されているものだと思うのですが。
    またメモリ上に展開されるHTMLソースが複合されているのはSSL通信でも同じ事だと思います。
    暗号化されていない公衆無線LANなどでパケットをキャプチャされてもバレなければ問題ないと思っています。
    -
  • 入力値のトリムはやめるようにしたいと思います。
    SHTTPにはいろいろと問題がありましたので仕組みを再考して出直します。
    ご回答ありがとうございました。
    -

よく考えてあるなーとは思うのですが、いくつか疑問点。

  • CAは、サーバとクライアントのペアをどうやって識別するのでしょうか?
    Script URLと言うのがこのための識別子のように思うのですが、これは実際にはセッションIDなどを含む、クライアントを識別できるような厳格な識別子になるのかな?

  • Script URLは盗聴可能ではないでしょうか?
    Return HTMLでクライアントはサーバからScript URLを受信し、これを使用してCAへcommon keyを取得しに行くように見えます。
    これって盗聴可能ではないでしょうか?
    Script URLはある意味暗号化通信の秘密鍵であるcommon keyに準ずる秘密情報だと思うのですが、第三者がこれを取得してCAに問い合わせれば、秘密鍵ゲットできそうな。
    盗聴されても平気な仕組みになっていれば話は変わってきますけれど。

  • 暗号化方式は固定でしょうか?
    SSLではSSLセッション確立時に、サーバとクライアント間で手持ちの使用可能な暗号化方式を提示し、相談の上どれを使うか決定しています。このプロセスが存在しませんが、AES固定でしょうか?もしそうだとUAが限定されたり、将来性に難がありそうです。

まだ出てくるかもしれませんが、今気になったのはこの辺です。

======================================
コメントを受けて追記。(2013/09/02 21:00)

一度アクセスされたら以後はステータスコード304を返しています。

真っ当なクライアントが常に一番最初に来ることは保障できないのでは?
例えば無線LANルータやプロキシが盗聴者だった場合などは、Man In The Middle攻撃が成功しませんか?
また、ネットワーク遅延なり瞬断なりでUAが正常にCAからcommon keyを取得できなかった場合にリトライできませんが、最初のフローからやり直しなんでしょうか。

あと、AES固定で行くとして、このSHTTPが普及期に入った5年後あたりには脆弱な暗号化方式になっている可能性は結構ありそうな気がしています。

根本的な話ですが、Open SHTTP CAは従来のCAの証明書発行能力に加えてサーバやクライアントからのリクエストを捌く能力がさらに必要になるようなんですが、現状のSSLより安価になるんでしょうか。

http://qiita.com/kawaz/items/f90810b9ea823b6556a8

ここにあるようにCAであること=無条件に信頼されることであり、信用を維持するのにコストがかかるから証明書の値段に跳ね返ってきているわけで。
サーバ証明書の代わりにScript URLをCAがサーバに対して発行する訳で、よくよく考えてみると少々形の変わったSSLになってるだけのようにも思えてきました。
CAはScript URLを通じて、サーバの実在証明(クライアントがまさにアクセスしようとしている本物である証明)をしているんですよね?

=========================================
さらに追記。(2013/09/03 10:00)
ごちゃごちゃになってきてすいません。。。

改めてよく考えてみたらMIM攻撃は成功しないのかな。
Script URL盗聴してcommon keyをクライアントより先に取得しても、そのカギは使われないし。
(クライアントは使用済みScript URLでアクセスするのでcommon keyをもらうことができず、最初からやり直し)

ただ、CAはServeに対して何らかの認証を行っているわけではない場合は、そもそも根本的に暗号化通信の意味をなしていないと考えます。
CAは単にWebサービスとして待ちうけていて、サーバとクライアントにSSL上で共通鍵を交換できる仕組みを提供するのみで、相手が誰であるかを保証していない場合。

編集 履歴 (4)
  • サーバとクライアントのペアはScrypt URLの中に書いているパラメータで識別します。
    このScrypt URLは盗聴可能ですが、一度アクセスされたら以後はステータスコード304を返しています。第三者に共通鍵を横取りされた場合には入力画面が表示しません。
    暗号化方式はAES固定です。テストはしていないのですがJSのみで暗号化しているためUAを選ばないで利用できると考えています。
    -
  • ご意見ありがとうございます。考え方は大変参考になりました。
    用途としてHTTPSを使わずに平文で「お問い合わせ」フォームを設置しているサイトや期間限定のアンケートなど証明書を取るほどでもないサイトの運営者が気軽に無料で使用してもらうために作りたいと思ったのですが、中間者攻撃・Server認証などの問題をふまえて仕組みを再考してみます。
    結局使えないという結論に至る可能性もあるのですが…
    -
  • こういう考察ってとても大事だと思いますし、着眼点は素晴らしいと思いますよ。楽しく技術論できておもしろかったです。 -

まずSHTTP CAなんですけど、これが共通鍵を知っているのはどうかなあ?と思います。共通鍵はCLIENT-SERVER間だけの秘密にしたいはずだと思うので。第三者であるSHTTP CAに知られているのはまずくないですか?鍵交換は素直にDiffie-Hellman鍵交換でよいのではないかと思います。

次にSERVERの認証がない点なんですけど、それだと中間者攻撃ができるのではないかと思います。攻撃者がCLIENT-SERVER間に割り込んでいて、CLIENTに対してはSERVERになりすまし、SERVERに対してはCLIENTになりすますとします。

攻撃者はSERVERから本物のReturn HTMLを受け取ります。しかし攻撃者はReturn HTMLを差し替えて嘘のscript URL(自分のURL)をCLIENTに返します。CLIENTは攻撃者のscript URLから偽の共通鍵を受け取ります。攻撃者は本物のscript URLから本物の共通鍵を受け取ります。

暗号化通信フェーズではCLIENT-攻撃者間は偽の共通鍵による暗号化が行なわれ、攻撃者-SERVER間は本物の共通鍵による暗号化が行なわれます。そんな感じで盗聴ができそうに思ったんですけど、どうでしょう?

もしこの理解で合っているなら、SERVERの認証はしたほうがよいと思います。

編集 履歴 (0)
  • SHTTP CAは共通鍵を持たない仕組みにしたいと思います。
    中間者攻撃についてはどう防ぐか十分な検討が必要ですね。
    ご回答ありがとうございます。
    分かりやすい説明でとても参考になりました。
    -
ウォッチ

この質問への回答やコメントをメールでお知らせします。