携帯電話用のGoogle/Microsoft Authenticatorアプリを使用して、MFAを追加するオンラインアプリケーションがあります。私はMFAシークレットを保存するためにセキュリティに焦点を当てたアプローチを採用しようとしましたが、現時点では、そのシークレットはデータベースフィールド内のユーザーパスワードを使用して暗号化されています。パスワード自体は保存しませんが、パスワードのハッシュを使用して、実行時にユーザーが送信したパスワードと比較して比較します。
この方法論には欠陥があり、ユーザーが自分のパスワードを忘れてパスワードの変更を要求したときです。その時点では、ユーザーのシークレットを(古いパスワードを使用して)復号化する方法がないため、送信された新しいパスワードを使用してシークレットを復元できます。
他の人がこれにどう対処するのかと思っていましたか?私の考えでは、次の選択肢があります。
(1)はユーザーにとって最も簡単ですが、最適ではないようです。QRコード(または同等のもの)をスキャンして新しいアカウントをセットアップする前に、(以前の)アカウントをアプリから削除する必要があります。
(2)アイデアは好きですが、どうしたらいいのでしょうか。ユーザーのパスワードなしでプログラムですべてを復元できるので、ユーザーのメールアドレスのハッシュを暗号化文字列として使用することを考えましたが、十分に安全かどうかはわかりません。
誰かが可能な解決策を探す場所についてここでいくつかのガイダンスを私に与えることができますか?
それはすべてあなたのスレッドモデルとシナリオに依存すると思います。たとえば、リークされたバックアップやSQLインジェクションによって、攻撃者が2FAのシークレットを含むテーブルにアクセスした場合に何が起こるかを恐れているということを私は読んでいます。
これが事実である場合、システム全体の鍵を使用して秘密を暗号化できます。これは、いくつかの鍵保管庫からアプリケーションにロードされます。これにより、鍵の保存場所と暗号化された秘密の保存場所が分離されます。ただし、アプリケーションは両方にアクセスできる必要があります。
キーがユーザーから派生したものである場合、攻撃者が同じことをする危険が常にあります。
私の最後のプロジェクトでは、他のアプリケーションと比較して、異なる言語で記述され、異なるデータストレージを使用する専用のMfaServiceを作成することにしました。このサービスは、シークレットを保存し、コードの有効性をチェックできるように書かれていますが、二度と機密を明らかにすることはありません。ユーザーサービスは、MFA資格情報への参照のみを保存しました。したがって、攻撃者は両方のサービスにアクセスする必要がありますが、これは私たちのユースケースには十分です。
ユーザーのパスワードに従って暗号化されたMFAシークレットを保存することになりました。これは、最も安全な方法だと思います。ユーザーがパスワードを変更するようになると(90日ごとに行う必要があります)、古い/既存のパスワードを使用してシークレットを復号化し、新しいパスワードを使用して再暗号化する必要があります。実行していますが、セキュリティが、取り組んでいる他のセキュリティ要素と一致していることに満足しています。