免責事項: bcrypt を使用して ユーザーのパスワードを安全に保存 を使用する必要があることはわかっています。読んでください。
ユーザーごとに複数のメールサービスの認証情報を保存したい。したがって、ユーザー名とパスワード(適切にハッシュ化されている)でログインすると、imapを介して、@ hotmail 2、@ gmail、大学1つ、その他いくつかのメールにアクセスできます。私はメールを読むためにimapを使用していますが、プレーンテキストのメールとパスワードが必要です。 では、これらのパスワードを安全に保存するにはどうすればよいですか?
私が考えたこと:
一部のサービスはAPIを提供します。可能な限りそれらを使用してください。
各ユーザーの資格情報をログインパスワードで暗号化して、ログインの詳細を知っているユーザーだけが資格情報を復号化して、電子メールにアクセスできるようにします。これを適切に行う方法がわからないので、ここに助けが必要です。私はmcrypt_encrypt()
をPHP with MCRYPT_RIJNDAEL_256
。
ユーザーがログインするたびにパスワードを要求します。ユーザーが3つ以上のサービスに接続している場合、実用的ではありません。
TL; DR
後でimapで使用できるようにパスワードをデータベースに保存するにはどうすればよいですか?
すべてのパスワードマネージャーが直面する問題に直面します。彼らの解決策は、対称アルゴリズムを使用して機密データを暗号化し、各ユーザーのマスターパスワードを使用して、保存されているすべてのパスワードの復号化キーを導出することだと思います。このマスターパスワードは、スクリプト/アプリケーションを再起動するたびに、またはWebアプリケーションの場合はユーザーがログインするたびに入力する必要があります。
これは基本的に、2番目の箇条書きで説明するものです。必要な暗号化ツールは PBKDF2 です:送信時にユーザーのログインパスワードにこれを使用します。結果のキーは、MCRYPT_RIJNDAEL_256
を使用してデータベース内のパスワードを暗号化/復号化するのに適している必要があります。
余談ですが、新しいデータを暗号化するたびに、異なる初期化ベクトルを使用するようにしてください。
独自のSSO環境をデプロイすることを検討してください(「独自にロールする」とは言っていません)。
私が個人的に提供したものの1つは、Jasigの中央認証サービス( http://www.jasig.org/cas )です。これは、ユーザーがログインするための集中認証プラットフォームとして機能します。次に、「クライアント」アプリケーションは、CASと「CAS化」(統合)して、このサードパーティソフトウェアによってユーザーがすでに認証されている場合にユーザーのアクセスを許可する必要があります。
あなたの質問に関係して、私が提供したコンポーネントはそれらのClearPass拡張機能( こちら )でしたが、ハッシュよりも暗号化を利用するすべてのアプリケーションのようにセキュリティリスクを高めながら、クリアテキストの資格情報をプロキシすることができます( ここ )。
目的(ClearPass):一部のレガシーアプリケーションへのシングルサインオンを有効にするには、実際のクリアテキストパスワードを提供する必要がある場合があります。そのようなアプローチは必然的にセキュリティリスクを増大させますが、多くの機関はそれが「必要悪」であると認めました。
ClearPassトランザクションが正常に完了すると、ユーザーのログインとパスワードが入力されます。これはユーザーのアプリケーションログイン資格情報であることに注意してください。ユーザーが自分の代わりにサードパーティのメールサービスへの認証を処理するアプリケーションにログインするために使用するもの。
ログイン資格情報を入手したら、ClearPassを介してアプリケーションパスワードを何度も再要求し、最初にログインパスワードで暗号化したサービスパスワードをオンデマンドで復号化して、@ executifsで説明されている「パスワードマネージャ」の問題に対処できます。ユーザーのアプリケーションパスワードの保存はClearPassによって処理され、EncryptedMapDecoratorによって暗号化され、メモリ(またはmemcachedなど)に保存されます。
余談ですが、暗号化とClearPassを使用していたときにさっき書いた暗号化の実装についての wikiページ があります(そして、はい、Freenodeの## cryptoに提出されています。大衆を批判し、必要に応じて修正されます).
実際のコードについては、 Java 、 Node。 、および C# の例をいくつか示します。最後の2つは基本的にEncryptedMapDecorator.Java
の私のポートであり、パスワードベースの鍵の導出(パスフレーズに基づいて秘密鍵を導出する)、初期化ベクトル(安全なランダムバイト)、さらにはパッキングに注意してください。ここでまとめたリソースとこれらのコード例を調べた後、これをPHPに移植するための十分な知識が必要です。少なくとも、とにかく始めましょう:)
これのいくつかが役に立てば幸いです!
この質問の複製としてマークされている answer to this question を共有する価値があると感じました。
クレデンシャルストレージは暗号の秘密を保存するのに最適だと思います。セキュリティのニーズに応じて、次の選択肢から選択できます-
- ソフトウェアベースの資格情報ストレージ
- システム管理の資格情報ストレージ
- ハードウェアベースの資格情報ストレージ
このブログを読むことをお勧めします 暗号化キーのストレージオプションとベストプラクティス 。ほとんどの場合、システム管理の資格情報ストレージが適切な選択です。多くのオペレーティングシステムは、システム管理の資格情報ストレージを提供します(例: Windows Certificate Store 、Mac OS Keychain )。また、私の answer on Android Keystore Systemを見て、アイデアを得ることができます。プラットフォームに応じて、秘密の資格情報を保存するための次のソリューションを提供できます。
- サーバーがLinuxの場合、使用できます Linuxカーネルキーリング または Gnomeキーリング 説明- ここ
- Windowsサーバーの場合、 Microsoft CryptoAPI を使用できます。スタックがJavaの場合、これは ドキュメント が役立ちます。