0

現在取り組んでいる Web サイト用の新しい暗号化システムを作成しようとしています。可能であれば、開始する前に誰かにセンスチェックしてもらうことができるかどうかを確認したかったのです!

更新: 元の質問でより明確になっているはずです。後でデータを読み戻せるようにするために、一部のユーザー データを暗号化する必要があります。また、ログイン時にユーザーを確認するために、ユーザーのパスワードまたはパスワードのハッシュも保存する必要があります。

計画は次のとおりです。

  1. マスター キー: DPAPI キー セッター アプリケーションを作成して、テキスト ベースのマスター キーを取得し、DPAPI を介して暗号化し、暗号化された出力をサーバー上のテキスト ファイルに保存します。これは、サイトを新しいサーバーに移動するたびに実行する 1 回限りのタスクです。マスター キーは、AES 暗号化を実行するために使用されます。

  2. 新規ユーザー登録時:

    2.1. パスワードデータ/パスワードデータのハッシュを保存します。

    2.2. マスター キー ファイルをロードし、DPAPI を使用してキーを復号化します。復号化されたマスター キーと、各ユーザー データの新しいランダム IV を使用して、AES で暗号化された文字列を作成します。暗号化された文字列の前に対応するランダムな IV を付けて、暗号化された各文字列を保存し、データベースの varchar 列に挿入します。

  3. ユーザーのログイン時:

    3.1. パスワード ハッシュを照合してユーザーを検証します。

    3.2. 暗号化されたユーザー データ フィールドごとに、コンテンツを IV と暗号化されたデータの 2 つの部分に分割します。DPAPI からマスター キーと IV を取得し、データを復号化して画面に表示します。

それはどのように聞こえますか?上記に明らかな欠陥はありますか?

私は過去にこの種のものに Enterprise Library Security を使用していたので (これは .NET コアでは使用できなくなりました!)、これに慣れていないので、どんな助けも大歓迎です!

4

2 に答える 2

2

回避できる場合は、パスワードを保存しないでください。

ステップ 1 のパスワードがわかりません。ステップ 2 まで新しいユーザーが表示されない場合、これは誰のパスワードですか?

とにかく、ユーザーにとってより良い計画は、派生素材を使用/保存することです。たとえば、新しいユーザー登録時に次のようにします

byte[] exportBytes;
byte[] exportSalt;
int exportPasswordSettingsVersion = YourSystemConfiguration.NewPasswordSettingsVersion;

using (Rfc2898DeriveBytes registerer = new Rfc2898DeriveBytes(
    newUserPassword,
    YourSystemConfiguration.GetSaltSize(exportPasswordSettingsVersion),
    YourSystemConfiguration.GetIterationCount(exportPasswordSettingsVersion)))
{
    exportSalt = registerer.Salt;

    exportBytes = registerer.GetBytes(
        YourSystemConfiguration.GetDerivedKeySize(exportPasswordSettingsVersion));
}

次に、salt バイト (ランダムに生成されたもの)、派生パスワード バイト、sett をユーザー プロファイルの一部としてエクスポートします。ユーザーがログインするときに、これらの値を読み込んで、それらが一致することを確認します。

using (Rfc2898DeriveBytes verifier = new Rfc2898DeriveBytes(
    inputPassword,
    loadedProfile.Salt,
    YourSystemConfiguration.GetIterationCount(loadedProfile.PasswordSettingsVersion)))
{
    byte[] verifyBytes = registerer.GetBytes(loadedProfile.PasswordVerify.Length);

    if (!ConstantTimeEquals(verifyBytes, loadedProfile.PasswordVerify))
    {
        return false;
    }

    if (loadedProfile.PasswordSettingsVersion < YourSystemConfiguration.GetIterationCount(exportPasswordSettingsVersion))
    {
        // Re-derive their password and save it with your newer (stronger, presumably) cryptographic settings.
    }

    return true;
}

このスキーム:

  • RFC2898 の PBKDF2 アルゴリズムを使用してパスワードからキーを導出します。資格情報データベースが危険にさらされた場合でもパスワードを漏らさないため、この導出された値を格納する方がパスワードを格納するよりも優れています。
  • 新しいユーザーごとに新しいランダム ソルトを使用します。(また、パスワードの変更またはアップグレードされたログインで再生成することもできます)
  • パスワードが設定されたときに使用された設定に関する情報を保存 (および読み込み) して、後でデフォルトを変更できるようにします。
  • DPAPI を使用しません (DPAPI は悪くありませんが、Windows 専用です。.NET Core を使用している場合は、クロスプラットフォーム ソリューションが必要になる場合があります)。
于 2016-07-17T00:41:54.650 に答える
1

パスワードの問題を無視し、ユーザー データだけを考慮すると、スキームは問題ありませんが、改善することができます。

基本的に、マスター キー (対称キー、または 16 バイトまたは 32 バイト) があり、保存時に (ディスク上で) 保護され、サーバー上のメモリでこれを復号化します。

ユーザー データはマスター キーを使用して暗号化され、データごとにランダムな IV が付けられます。暗号的に強力なランダム データを必ず使用してください。

IV と暗号文を一緒に保存していますが、これで問題ありません。ただし、IV と暗号文はバイナリであるため、blob データベース タイプを使用するか、Base64 を使用してバイナリをエンコードして varchar として格納する必要があります。

これに追加することを検討する必要があるのは、なんらかの形式の改ざん検出です。たとえば、2 つのマスター キーを使用できます。1 つは暗号化/復号化用、もう 1 つはデータの HMAC 用です。暗号化キーを使用してデータを暗号化し、IV + 暗号文に HMAC を適用し (HMAC の 2 番目のマスター キーを使用)、HMAC を IV および暗号文と共に保存します (単に追加することもできます)。復号化する前に、HMAC を検証します。これは、IV + 暗号文が変更されたかどうかを示します。

パディングについては言及していません。AES CBC モードを使用する場合、データが 16 バイトの倍数でない場合は、データをパディングする必要があります。パディングでは、攻撃者が任意の暗号文をサーバーに送信し、サーバーからの応答が攻撃者に「パディングエラー」または「無効な復号化」を伝える「パディングオラクル」を誤って提供しないように注意する必要があります。 " -- つまり、サーバーの応答に違いがあります。

AES GCM モードを使用する場合、HMAC に相当するものが組み込まれています。単一のマスター キーのみが必要であり、GCM 自体が暗号文の改ざんを検出します。これにより、暗号化の一部ではないが、「認証」に含まれる「関連データ」を含めることもできます。つまり、HMAC に含まれているかのようになります。たとえば、ユーザー名「Joe」は、Joe のデータの GCM 暗号化に関連データとして含めることができます。次に、GCM モードがデータを復号化すると、IV + 暗号文の改ざんが検出されるだけでなく、ユーザー名も「Joe」である必要があります。「Joe」はここでは暗号化されていないことに注意してください。

個々の IV を毎回ランダムに、データごとに使用するのは非常に良い考えです。また、マスター キーを交換するまでの使用期間についても考慮する必要があります。寿命は限られている必要があり、「ローテーション」または「ロール」または「再キー化」(すべて同じことを意味します-交換することを意味します) の場合は、すべてを再暗号化する何らかの方法が必要になります。マスター キーを定期的に (3 か月かもしれないし、1 年かもしれません) 変更して、1) マスター キーが危険にさらされた場合に公開されるデータの量を制限し (たとえば、3 か月分だけ)、2) 変更する必要があります。単一のキーが暗号化に使用されるデータの量 (技術的には、単一のキーで暗号化でき、数学的に「安全」であるデータ量には制限があるため)。

于 2016-07-17T18:32:49.220 に答える