web-dev-qa-db-ja.com

C#でRfc2898DeriveBytesでSystem.Stringを使用しないようにする方法

ユーザーのパスワードを取り込み、ハッシュしてサーバーに格納する.NETコアWebアプリケーションをC#で作成しています。ランダムに生成されたソルトと共にRfc2898DeriveBytesを使用しています。ただし、文字列はメモリから削除できないため、プロセス全体で文字列を使用することは避けなければならないことを読みました。 .NETコアには、パスワードをPasswordBoxとして保持するSecureStringがあることを知っていますが、SecureStringsをRfc2898DeriveBytesに渡すバイト配列に変換できません大量の悪意のないコンストラクタ。

Webappは私のサーバーでのみ実行されるので、SecureStringをwebappに渡されたらすぐに文字列に戻すことができますか?攻撃者がサーバーのRAM=にアクセスして、削除されていない文字列を検索した場合、最初から何かを保護するために私ができることはほとんどありません。

それでもSecureStringsを使用する必要がある場合、それを格納するためにハッシュするためのベストプラクティスは何ですか?

27
Jeff

SecureStringを正しく使用することは困難であり、ほとんどの使用例ではありそうもない脅威の表面から保護します。あなたが言うように、攻撃者があなたの記憶を読むことができるならば、あなたは他の問題を抱えています。サーバーに物理的にアクセスして攻撃者 液体窒素を運ぶ を心配しない限り、SecureStringではなく通常の文字列を使用することをお勧めします。

SecureStringsを本当に使用したい場合は、メモリを制御できるように、Windowsの暗号化APIをP/Invokeする必要があります。私のブログ投稿に例があります 。NETでの安全な文字列の比較

34
Sjoerd

.NET Coreチームは、新しい開発にSecureStringを使用しないことを特に推奨しています。 SecureStringのドキュメント を参照してください:

新規開発にSecureStringクラスを使用することはお勧めしません。詳細については、GitHubのSecureStringを使用しないでくださいを参照してください。

同様に GitHubでのチームの推論

動機

  • SecureStringの目的は、シークレットをプレーンテキストとしてプロセスメモリに格納しないようにすることです。
  • ただし、Windowsでも、SecureStringはOSの概念として存在しません。
    • それは単にウィンドウのプレーンテキストを短くするだけです。 .NETは文字列をプレーンテキスト表現に変換する必要があるため、完全に防ぐことはできません。
    • 利点は、プレーンテキスト表現がSystem.Stringのインスタンスとして滞留しないことです。ネイティブバッファの寿命が短くなります。
  • 配列の内容は、.NET Framework以外では暗号化されません。
    • .NET Frameworkでは、内部文字配列の内容は暗号化されています。 APIがないか、キー管理の問題があるため、.NETはすべての環境で暗号化をサポートしていません。
49
Vivelin