2012-01-24 8 views
1

セッションの原則は、対応するセッションIDを持つユーザーだけがアクセスできるサーバー側にデータを保存することです。セッションの代わりにhmacベースのクライアントデータ検証を使用しますか?

データには、クライアントとの関係でプライベートまたはパブリックの2種類があります。セッションはもちろん、公共のアクセスのためにプライベートです。

私は通常、ユーザーIDといくつかのランダムなデータを格納しています(具体的な例はありません)。

私はセッションを全く使用しないことを考えています。代わりに、ユーザーが送信したデータの有効性をチェックする関数を使用します。サーバーには、ユーザーデータをハッシュするために使用するプライベートキーがあります。

たとえば、ユーザーがid = 9999を持つ場合、通常、ユーザーはセッションIDに関連付けられたファイルに格納します。クライアントがリクエストを行うたびに、セッションIDを確認し、それに関連付けられたセッションファイルからデータを取得します。

私はクライアント側でセッションデータを保存することを考えており、クライアントが要求を行うたびにこのデータとデータのハッシュを送信します。

ユーザーがログインすると、ユーザーは資格情報を送信し、サーバーはそのIDにタイムスタンプとユーザーIDと秘密キーに基づいて計算されたハッシュを返します。 今後のリクエストに対して、サーバーは同じ機能を使用し、結果のハッシュが同じ場合、セッションは有効であり、データは事前​​に検証されています。

セッションを置き換える有効な方法ですか? サーバープライベートセッションデータを保存しない以外に何か欠点がありますか?

私はスピードに関係だったと私は、私はノートPC(インテルデュオ)上でこれを実行しました

Script took 5.246542930603 seconds 

を印刷し、小さなテスト...

<?php 

$session = array(
    'userId' => 999, 
    'timestamp' => time() 
); 
$privateKey = 'da39a3ee5e6b4b0d3255bfef95601890afd80709'; 

$startTime = microtime(true); 

for ($i = 0; $i < 1000000; $i++){ 
    $hash = hash_hmac('sha1', json_encode($session), $privateKey); 
} 

echo 'Script took ' . (microtime(true) - $startTime) . ' seconds'; 

を...作りました。 これは手頃な時間です(0.000005247 /ハッシュ)。 テストは正しいですか?

EDIT:セッションの有効期限を保証するために、タイムスタンプがユーザーIDとともにハッシュされます。サーバー側では、セッションが有効であっても、それが古すぎるとしても期限切れと見なすことができます。

プライベートキーを使用してタイムスタンプとともにデータをハッシュしているのであれば、実稼働環境で使用することができますか?私はいくつかの欠点を考えることができ

+2

ViewStateとセッションを調べるのは興味深いかもしれません。 .Netに精通している方がより意味をなさないでしょうが、関連する原則は基本的にここで検討しているものと同じです。 –

+0

チケット発行システムは、多くのデータをセッションに入れないで、セキュリティを維持し続ける典型的な方法です。私はほとんどの場合ウェブサイト用のチケット発行システムを実装し、チケットをセッション変数、CookieまたはURLパラメータに入れます。 –

+0

Phoenix氏のように、ViewStateテクノロジーを探しています。私は以前に実装したことがあります。トリックは、後でurlencodeするシリアライズ可能なオブジェクトを作成するだけで、ユーザーはデータを簡単に読み取ることができず、urlencodedデータからハッシュを作成できるため、ViewStateがまだ有効かどうかを検証できますそれを使用する前に有効です... –

答えて

5

...

  1. すべてのクッキーデータを要求遅くなって、各HTTPリクエストに転送されます。
  2. ユーザーはすべてのデータを見ることができます。
  3. ハッシュの有効性を確認する必要があるため、 またはスペースがどれだけ節約されているか分かりません。
  4. ハッシュをリバースエンジニアリングすることができます(つまり、何らかのプライベートキー暗号化を使用していない)場合、ユーザーは何かを送信することができ、それが有効であると言います。
  5. リバースエンジニアリングができないハッシュがある場合は、生成が多少遅くなる可能性があります。秘密鍵を使用していると言いますので、これが当てはまります。ソリューションがうまく拡張できない可能性があります。
  6. あなたが何をしたのか不思議に思った後、誰でもこのコードを維持しなければなりません。
+0

@AalexGabi:残念ながら、すべての点が有効です。あなたはセッションデータをユーザーに公開しています(簡単に読むことができます)。また、インターネットを介してこのデータを送信しています(接続が安全でない場合は、基本的にユーザーに個人データを伝えています)。正当なアクセスと悪意のあるアクセスを区別することさえできません。さらに、あなたのソリューションは標準ではないため、設計上の欠陥のためにいつかは失敗し、とにかく何かに置き換えられる可能性があります。 – Tadeck

+0

1.有効なポイントです。これは、セッションに格納する必要があるデータの量によって異なります。 2.問題の特定。 3.スピードテストのテストを追加しました。 Memcacheや複数のWebサーバー用の他のセッションストレージから私たちを救います。 4.秘密鍵を使用すると、リバースエンジニアリングが非常に難しいと思う。 5.私はhmac_sha1を使用することについて考えていますが、それは私の意見では速いです。 6.それが文書化されていれば、それは問題ではないと私は信じています。とにかく、このメカニズムはあまり複雑ではありません。 –

+0

@Tadeck私は、セッションIDまたはユーザIDを含むクッキーを持つことの違いは何もわかりません!誰かがセッションIDと基本的にHTTPヘッダーを持っている場合、彼は簡単にユーザーとして自分自身を認証できます(ユーザーIDも知っています)。セキュリティの観点からは、HTTPヘッダーに直接ユーザーIDが表示されていること、および/またはこのデータを格納する方法が使用されているかどうかに応じてparamsを取得する点が異なります。 –

0

これについての唯一の良いことは、sessiond_idを覚えておく必要がないことです。それはあまりにも多くの仕事です。私はそれがViewStateと呼ばれているかどうかはわかりませんでしたが、最終的に圧縮されたデータをクライアント側の隠しフィールドにすべて格納しました。おそらく、暗号化の代わりに圧縮を使用することをお勧めしますか?それはあいまいさによるセキュリティです。

+0

ViewStateは、ASP.NETの最も基本的な概念です。文字列から直列化および非直列化できるオブジェクトの配列を取得し、配列をエンコードします(暗号化はしていませんが)。結果は隠しフォームフィールドになります。これは、この質問で議論されている利点と欠点のほとんどすべてを持っています。 – Andrew

+0

セッションを使用しないという考えは、複数のWebサーバーがある場合にセッションIDを実際に覚えておくことが重要です。 Memcachedを使用する必要があります。ロードバランサはおそらくあなたのセッションを持たないリストから1つのWebサーバーをランダムに(ほとんど)選択するため、サーバー間でこれらのセッションを共有するためにNFSなどを使用します。 –

+0

@AalexGabi私はそれを自分で調べていませんが、ここにデータベースサーバーオプションがあります(ASP.NETのようにSQL Serverを使用してセッション状態を保存できます)。私はそれがあなたが提案しているものよりも実行可能か本質的に優れていると言っているわけではありませんが、別の選択肢です。さらに別のオプションは、セッションデータを取得するためのバックエンドWebサービスとして機能するバックエンドの「セッションサーバー」(ここでもASP.NETで「できる」もの)です。 _too_をセッションの状態で保存していない場合は、データをクライアント側から遠ざけたい場合は、これが別のオプションになる可能性があります。 – Andrew

関連する問題