デフォルトでは、Ruby on Rails はセッション データを Cookie に保存します。これには、サーバー側で永続化レイヤーをセットアップする必要がないなど、多くの利点があります。ただし、セッション データは暗号化されておらず、私が作成している Rails アプリは、潜在的に機密性の高いデータをセッションに配置します。セッションデータをサーバー側に保存することはできれば避けたいのですが、既存の Rails 用の暗号化 Cookie ストアの実装だけが放棄されているようです。そのため、独自の暗号化 Cookie ストアを作成しています。
Rails Cookie セッション ストアは次のように機能します。
- セッション データをバイト文字列にシリアル化します。
- シリアル化されたデータは base64 に変換されます。
- base64 データは HMAC によって追加されます。Rails では、HMAC 秘密鍵が少なくとも 30 バイトである必要があります。Rails はデフォルトで、/dev/urandom から取得した 128 バイトのランダムな文字列を秘密鍵として生成します。HMAC に使用されるデフォルトのハッシュ アルゴリズムは SHA-1 です。
- base64 データ + HMAC が Cookie として HTTP クライアントに送信されます。
- クライアントがリクエストを実行すると、Rails は最初に HMAC 検証が成功するかどうかを確認します。そうでない場合は、ユーザーがセッション データをまったく送信していないかのように、Cookie 内のセッション データを黙って破棄します。これは、管理者が HMAC シークレット キーを変更すると、すべての古いセッションが自動的に無効になることも意味します。
- base64 データは de-base64 され、Ruby データ構造にアンマーシャリングされます。
私が書いている暗号化された Cookie セッション ストアは、通常の Cookie ストア クラスのサブクラスです。次のように機能します。
- ステップ 3.5 を挿入します。ステップ 3 の後、データを暗号化します。
- ステップ 5 を変更します。HMAC をチェックする前に、データを復号化します。
- 暗号化アルゴリズムは CFB モードの AES-256 です。EBC が繰り返しパターンを公開することを理解しています。
- このコードでは、管理者が正確に 32 バイトの暗号化キーを指定する必要があります。暗号化キーはハッシュされません。デフォルトでは、ランダムに生成された正確に 32 バイトの暗号化キーが提案され、/dev/urandom から取得されます。
- また、管理者は正確に 16 バイトの初期化ベクトルを指定する必要があります。IV はハッシュ化されておらず、デフォルトでは、/dev/urandom から取得されたランダムに生成された IV が提案されます。
(暗号化後の HMAC ではなく) 暗号化前に HMAC を使用する理由は、暗号化キーまたは IV の変更を検出できるようにするためです。暗号化キーまたは IV が変更された場合に、ソフトウェアが古いセッションを自動的に無効にするようにしたい。暗号化後に HMAC を使用すると、暗号化キーまたは IV を変更すると HMAC 検証がパスしますが、これは望ましくありません。
私のアプローチは安全ですか?そうでない場合、何が欠けていますか?
いくつかのメモ:
- http://www.daemonology.net/blog/2009-06-11-cryptographic-right-answers.htmlで推奨されている CTR を使用したいのですが、残念ながら OpenSSL (Ruby 標準ライブラリに含まれています) は使用できません。 CTR をサポートしていないため、ユーザーに別のサード パーティの暗号化ライブラリをインストールするよう要求したくありません。
- HMAC に SHA-256 を使用したい。daemonology.net は、「32 ビット システムに対するサイドチャネル攻撃」の可能性があるため、SHA-512 を推奨していません (それが何を意味するにせよ)。ただし、HMAC のハッシュ アルゴリズムとしての SHA-256 は、すべてのプラットフォームでサポートされているわけではありません。最も注目すべきは、OS X で出荷された Ruby が HMAC+SHA256 をサポートしていないことです。私のコードは、OS X でもすぐに動作するようにしたいと考えています。