ユーザーのパスワードを取り込み、ハッシュしてサーバーに格納する.NETコアWebアプリケーションをC#で作成しています。ランダムに生成されたソルトと共にRfc2898DeriveBytes
を使用しています。ただし、文字列はメモリから削除できないため、プロセス全体で文字列を使用することは避けなければならないことを読みました。 .NETコアには、パスワードをPasswordBox
として保持するSecureString
があることを知っていますが、SecureString
sをRfc2898DeriveBytes
に渡すバイト配列に変換できません大量の悪意のないコンストラクタ。
Webappは私のサーバーでのみ実行されるので、SecureString
をwebappに渡されたらすぐに文字列に戻すことができますか?攻撃者がサーバーのRAM=にアクセスして、削除されていない文字列を検索した場合、最初から何かを保護するために私ができることはほとんどありません。
それでもSecureStrings
を使用する必要がある場合、それを格納するためにハッシュするためのベストプラクティスは何ですか?
SecureStringを正しく使用することは困難であり、ほとんどの使用例ではありそうもない脅威の表面から保護します。あなたが言うように、攻撃者があなたの記憶を読むことができるならば、あなたは他の問題を抱えています。サーバーに物理的にアクセスして攻撃者 液体窒素を運ぶ を心配しない限り、SecureStringではなく通常の文字列を使用することをお勧めします。
SecureStringsを本当に使用したい場合は、メモリを制御できるように、Windowsの暗号化APIをP/Invokeする必要があります。私のブログ投稿に例があります 。NETでの安全な文字列の比較 。
.NET Coreチームは、新しい開発にSecureStringを使用しないことを特に推奨しています。 SecureStringのドキュメント を参照してください:
新規開発にSecureStringクラスを使用することはお勧めしません。詳細については、GitHubのSecureStringを使用しないでくださいを参照してください。
同様に GitHubでのチームの推論 :
動機
SecureString
の目的は、シークレットをプレーンテキストとしてプロセスメモリに格納しないようにすることです。- ただし、Windowsでも、
SecureString
はOSの概念として存在しません。
- それは単にウィンドウのプレーンテキストを短くするだけです。 .NETは文字列をプレーンテキスト表現に変換する必要があるため、完全に防ぐことはできません。
- 利点は、プレーンテキスト表現が
System.String
のインスタンスとして滞留しないことです。ネイティブバッファの寿命が短くなります。- 配列の内容は、.NET Framework以外では暗号化されません。
- .NET Frameworkでは、内部文字配列の内容は暗号化されています。 APIがないか、キー管理の問題があるため、.NETはすべての環境で暗号化をサポートしていません。