web-dev-qa-db-ja.com

サーバーにパスワードを安全に保存する方法は?

免責事項bcrypt を使用して ユーザーのパスワードを安全に保存 を使用する必要があることはわかっています。読んでください。

ユーザーごとに複数のメールサービスの認証情報を保存したい。したがって、ユーザー名とパスワード(適切にハッシュ化されている)でログインすると、imapを介して、@ hotmail 2、@ gmail、大学1つ、その他いくつかのメールにアクセスできます。私はメールを読むためにimapを使用していますが、プレーンテキストのメールとパスワードが必要です。 では、これらのパスワードを安全に保存するにはどうすればよいですか?

私が考えたこと:

  • 一部のサービスはAPIを提供します。可能な限りそれらを使用してください。

  • 各ユーザーの資格情報をログインパスワードで暗号化して、ログインの詳細を知っているユーザーだけが資格情報を復号化して、電子メールにアクセスできるようにします。これを適切に行う方法がわからないので、ここに助けが必要です。私はmcrypt_encrypt()をPHP with MCRYPT_RIJNDAEL_256

  • ユーザーがログインするたびにパスワードを要求します。ユーザーが3つ以上のサービスに接続している場合、実用的ではありません。

TL; DR

後でimapで使用できるようにパスワードをデータベースに保存するにはどうすればよいですか?

10

すべてのパスワードマネージャーが直面する問題に直面します。彼らの解決策は、対称アルゴリズムを使用して機密データを暗号化し、各ユーザーのマスターパスワードを使用して、保存されているすべてのパスワードの復号化キーを導出することだと思います。このマスターパスワードは、スクリプト/アプリケーションを再起動するたびに、またはWebアプリケーションの場合はユーザーがログインするたびに入力する必要があります。

これは基本的に、2番目の箇条書きで説明するものです。必要な暗号化ツールは PBKDF2 です:送信時にユーザーのログインパスワードにこれを使用します。結果のキーは、MCRYPT_RIJNDAEL_256を使用してデータベース内のパスワードを暗号化/復号化するのに適している必要があります。

余談ですが、新しいデータを暗号化するたびに、異なる初期化ベクトルを使用するようにしてください。

7
executifs

独自のSSO環境をデプロイすることを検討してください(「独自にロールする」とは言っていません)。

私が個人的に提供したものの1つは、Jasigの中央認証サービス( http://www.jasig.org/cas )です。これは、ユーザーがログインするための集中認証プラットフォームとして機能します。次に、「クライアント」アプリケーションは、CASと「CAS化」(統合)して、このサードパーティソフトウェアによってユーザーがすでに認証されている場合にユーザーのアクセスを許可する必要があります。

あなたの質問に関係して、私が提供したコンポーネントはそれらのClearPass拡張機能( こちら )でしたが、ハッシュよりも暗号化を利用するすべてのアプリケーションのようにセキュリティリスクを高めながら、クリアテキストの資格情報をプロキシすることができます( ここ )。

目的(ClearPass):一部のレガシーアプリケーションへのシングルサインオンを有効にするには、実際のクリアテキストパスワードを提供する必要がある場合があります。そのようなアプローチは必然的にセキュリティリスクを増大させますが、多くの機関はそれが「必要悪」であると認めました。

ClearPassトランザクションが正常に完了すると、ユーザーのログインとパスワードが入力されます。これはユーザーのアプリケーションログイン資格情報であることに注意してください。ユーザーが自分の代わりにサードパーティのメールサービスへの認証を処理するアプリケーションにログインするために使用するもの

ログイン資格情報を入手したら、ClearPassを介してアプリケーションパスワードを何度も再要求し、最初にログインパスワードで暗号化したサービスパスワードをオンデマンドで復号化して、@ executifsで説明されている「パスワードマネージャ」の問題に対処できます。ユーザーのアプリケーションパスワードの保存はClearPassによって処理され、EncryptedMapDecoratorによって暗号化され、メモリ(またはmemcachedなど)に保存されます。

余談ですが、暗号化とClearPassを使用していたときにさっき書いた暗号化の実装についての wikiページ があります(そして、はい、Freenodeの## cryptoに提出されています。大衆を批判し、必要に応じて修正されます).

実際のコードについては、 JavaNode。 、および C# の例をいくつか示します。最後の2つは基本的にEncryptedMapDecorator.Javaの私のポートであり、パスワードベースの鍵の導出(パスフレーズに基づいて秘密鍵を導出する)、初期化ベクトル(安全なランダムバイト)、さらにはパッキングに注意してください。ここでまとめたリソースとこれらのコード例を調べた後、これをPHPに移植するための十分な知識が必要です。少なくとも、とにかく始めましょう:)

これのいくつかが役に立てば幸いです!

1
Matt

この質問の複製としてマークされている answer to this question を共有する価値があると感じました。

クレデンシャルストレージは暗号の秘密を保存するのに最適だと思います。セキュリティのニーズに応じて、次の選択肢から選択できます-

  • ソフトウェアベースの資格情報ストレージ
  • システム管理の資格情報ストレージ
  • ハードウェアベースの資格情報ストレージ

このブログを読むことをお勧めします 暗号化キーのストレージオプションとベストプラクティス 。ほとんどの場合、システム管理の資格情報ストレージが適切な選択です。多くのオペレーティングシステムは、システム管理の資格情報ストレージを提供します(例: Windows Certificate Store 、Mac OS Keychain )。また、私の answer on Android Keystore Systemを見て、アイデアを得ることができます。プラットフォームに応じて、秘密の資格情報を保存するための次のソリューションを提供できます。

0
Roaim