web-dev-qa-db-ja.com

デスクトップアプリから使用した場合のPasswordVaultセキュリティ

デスクトップアプリ(WPFベース)で Windows.Security.Credentials.PasswordVault を使用して、ユーザーのパスワードを安全に保存したいと思います。私はこれを使用してこのWindows 10 APIになんとかアクセスできました MSDN記事

私はいくつかの実験を行ったところ、1つのデスクトップアプリ(ネイティブUWPアプリではない)からPasswordVaultに書き込まれたデータは、他のデスクトップアプリから読み取ることができるようです。デスクトップアプリを Desktop Bridge テクノロジでパッケージ化してパッケージIDを設定しても、この脆弱性は修正されません。

それを修正し、アプリのデータを他のアプリから安全に保存できるようにする方法はありますか?

UPDATE:PasswordVaultは [〜#〜] dpapi [〜#〜] よりもセキュリティを強化しないようです。ケースはクローズされ、否定的な結果が出ます。

18

(これは私があなたの投稿について理解できることからのものです)

これらの種類のAPIを使用する場合、デスクトップアプリ間のデータアクセスを防止する実際の方法はありません http://www.hanselman.com/blog/SavingAndRetrievingBrowserAndOtherPasswords.aspx それについて詳しく説明します。あなたはおそらくあなたの情報を解読したいと思うでしょう。

メモリアクセスの制限は困難です。ユーザーが実行したコードは常にユーザーが取得できるため、これを制限することは困難です。

windowsデータ保護APIの使用を検討しました: https://msdn.Microsoft.com/en-us/library/ms995355.aspx

ソースから直接取得DPAPIは使いやすいサービスであり、パスワードや秘密キーなどの機密アプリケーションデータの保護を提供する必要がある開発者にメリットをもたらします

WDPAPIは、オペレーティングシステムによって生成されたキーとTriple DES=を使用してデータを暗号化/復号化します。これは、アプリケーションがこれらのキーを生成する必要がないことを意味します。これは常にいいことです。

Rfc2898DeriveBytesクラスを使用することもできます。これは、疑似乱数ジェネレータを使用してパスワードを復号化します。結果からパスワードに戻る実用的な方法がないため、ほとんどの復号化プログラムより安全です。これは、入力パスワードを確認し、再度取得するのではなく、本当に役立ちます。私はこれを実際に使用したことがないので、あなたを助けることはできません。

https://msdn.Microsoft.com/en-us/library/system.security.cryptography.rfc2898derivebytes(v = vs.110).aspx

私ができるよりも優れた説明を提供するこの投稿も参照してください。 ユーザー名/パスワード(ローカル)を安全に保存する方法

質問を誤解した場合は、教えてください。回答を更新します。

他の方法で引き続きアクセスできますが、モダン/メトロアプリにはこの問題はありません。

5
Lloyd

難しい真実は、デスクトップアプリケーションにパスワードを保存することは、100%安全に行うことは不可能であることです。 ただし、100%に近づくことができます。

元のアプローチに関して、PasswordVaultはウィンドウに組み込まれている Credential Locker サービスを使用してデータを安全に保存します。 Credential Lockerはユーザーのプロファイルにバインドされています。したがって、PasswordVaultを介してデータを保存することは、データを保護するためのマスターパスワードアプローチと基本的に同等です。これについては、後で詳しく説明します。唯一の違いは、その場合のマスターパスワードはユーザーの資格情報であることです。これにより、ユーザーのセッション中に実行されているアプリケーションがデータにアクセスできます。

注:明確にするために、プレーンテキストにアクセスできるように保存することについて厳密に話しています。つまり、あらゆる種類の暗号化されたデータベースに保存するか、自分で暗号化してどこかに暗号文を保存します。この種の機能は、パスワードマネージャーなどのプログラムでは必要ですが、何らかの認証のみを必要とするプログラムでは必要ありません。これが必要ではない場合は、パスワードをハッシュすることを強くお勧めします、理想的には、 this に示されている zaph による回答に従ってください。 ( this 優れた投稿の Thomas Pornin による詳細情報)。


が必要な場合、必要なものは少し複雑になります。他のプログラム(または私が推測するユーザー)がプレーンテキストのパスワードを表示できないようにしたい場合は、本当のオプションはそれを暗号化することです。暗号化をPasswordVaultに保存するかどうかは任意です。適切な暗号化を使用する場合、唯一の弱点は誰かがあなたの鍵を発見することです。したがって、暗号文自体はどこにでも保存できます。これで鍵自体が表示されます。

各プログラムインスタンスに対して実際に保存しようとしているパスワードの数によっては、キーを生成して安全に保存することを心配する必要がない場合もあります。複数のパスワードを保存したい場合は、ユーザーに1つマスターパスワードを入力するように要求し、それに対してソルティングとハッシュを実行して、他のすべてのパスワードの暗号化キーとして結果。復号化の時間になったら、ユーザーに再度入力するように依頼します。複数のパスワードを保存している場合は、このアプローチを使用することを強くお勧めします。これは可能な最も安全なアプローチです。しかし、私の投稿の残りの部分では、これは実行可能なオプションではないと仮定してロールします。

最初に、すべてのインストールで同じキーを使用することをしないことをお勧めします。安全に生成されたランダムデータに基づいて、プログラムのインスタンスごとに新しいものを作成します。システムに関する情報に基づいて、必要に応じてキーを即座に生成することにより、「キーを保存する必要がない」という誘惑に負けません。これは、プログラムにstring superSecretKey = "12345";をハードコーディングするのと同じくらい安全です。攻撃者がプロセスを理解するのに長い時間はかかりません。


今、それを保存するのは本当に難しい部分です。 infosecの一般的なルールは次のとおりです。

物理的にアクセスできるようになると、安全なものはなくなります

したがって、理想的には誰もそうしません。暗号化キーを適切に保護されたリモートサーバーに保存すると、攻撃者によって暗号化キーが復元される可能性が最小限になります。本全体がサーバー側のセキュリティに関して書かれているので、ここではこれについては説明しません。

別の良いオプションは、HSM( Hardware Security Module )を使用することです。これらの気の利いた小さなデバイスは、仕事のために構築されています。 HSMに格納されているキーにアクセスすることはほとんど不可能です。ただし、このオプションは、エンタープライズ環境などで、すべてのユーザーのコンピューターにこれらのいずれかがあることが確実にわかっている場合にのみ有効です。

.Netは、構成システムを介して、一種のソリューションを提供します。 app.configの暗号化されたセクションにキーを保存できます。これは、接続文字列を保護するためによく使用されます。これを行う方法については、たくさんのリソースがあります。 this 素晴らしいブログ記事をお勧めします。これにより、知っておくべきことのほとんどがわかります。


キーをその場で生成するだけではいけないことを先に述べた理由は、コードに変数として格納するのと同様に、obfuscationに排他的に依存してセキュリティを維持するためです。 。このアプローチの重要な点は、通常しないことです。ただし、他のオプションがない場合もあります。 White Box cryptography と入力します。

ホワイトボックス暗号化は、本質的には難読化を極端にしたものです。これは、攻撃者がバイトコードにアクセスでき、バイトコードを変更できるホワイトボックスのシナリオでも効果的であることを意味しています。これは、あいまいさによるセキュリティの縮図です。単なる一定の隠蔽(infosecがstring superSecretKeyアプローチについて話す)または必要なときにキーを生成するのとは対照的に、ホワイトボックス暗号化は本質的に暗号自体の生成に依存していますはえ。

papers 全体が書かれています。適切な実装を書くのは難しいので、走行距離が異なる場合があります。これを検討する必要があるのは、本当にreallyreallyこれをできる限り安全に実行したい場合のみです。


ただし、難読化は依然として難読化です。実際にできることは、攻撃者を遅くすることだけです。私が提供しなければならない最後のソリューションは逆に思えるかもしれませんが、それは機能します。暗号化キーをデジタルで隠さないでください。それを非表示にします物理的に。暗号化のタイミングでユーザーにUSBドライブを挿入してもらい、(安全に)ランダムなキーを生成してから、USBドライブに書き込みます。次に、復号化の時間になると、ユーザーはドライブを元に戻すだけでよく、プログラムはそのキーを読み取ります。

これは、キーを安全に保つためにユーザーに任せるという点で、マスターパスワードアプローチに少し似ています。ただし、いくつかの注目すべき利点があります。たとえば、このアプローチではmassive暗号化キーを使用できます。わずか1メガバイトのファイルに収まるキーは、ブルートフォース攻撃によって文字通り数十億の年月がかかる可能性があります。さらに、キーが発見された場合、ユーザーは自分だけに責任があります。


要約すると、暗号化キーを保存する必要を回避できるかどうかを確認します。できない場合は、locallyを絶対に保存しないでください。そうでなければ、あなたの唯一の選択肢は、ハッカーがそれを可能な限り理解するのを困難にすることです。どのように選択する場合でも、すべてのキーが異なることを確認してください。攻撃者がそのキーを見つけた場合でも、他のユーザーのキーは安全です。

4
stybl

唯一の代替策は、コードのどこかに格納されている独自の秘密鍵でパスワードを暗号化することです。 (誰かがコードを簡単に分解してキーを取得する可能性があります)その後、暗号化されたパスワードをPasswordVault内に保存しますが、セキュリティはアプリにしかアクセスできず、パスワードにアクセスできません。

これは二重のセキュリティであり、マシンが侵害された場合、攻撃者はPasswordVaultにアクセスできますが、パスワードを解読するためにもう1つの秘密鍵が必要であり、コードのどこかに隠されているため、パスワードは取得できません。

安全性を高めるために、サーバーに秘密鍵を残し、Vaultに保存する前にパスワードを暗号化および復号化するAPIを公開すると、最も安全になります。これが、パスワードをボールトに保存するのではなく、OAuth(OAuthトークンをPasswordVaultに保存)など)に移行した理由だと思います。

理想的には、パスワードを保存せずに、サーバーからトークンを取得して保存し、そのトークンを認証に使用することをお勧めします。そして、そのトークンをPasswordVaultに保管します。

2
Akash Kava

さまざまな暗号化およびストレージ戦略を使用して、セキュリティをプッシュすることは常に可能です。何かをより困難にすることは、データ取得をより長くするだけであり、決して不可能ではありません。したがって、実行コストx時間(人とマシン)および開発コストx時間の側面を考慮して、最も適切な保護レベルを検討する必要があります。

リクエストを厳密に考慮した場合、レイヤー(クラス、インターフェイス)を追加して、パスワードを暗号化します。 (RSAではなく)非対称暗号化に最適です。他のソフトがプログラムデータ(プログラム、ファイルORプロセス))にアクセスしていない場合、これで十分です。SSH.NET( https://github.com/ sshnet/SSH.NET )これをすばやく実現します。

セキュリティをプッシュし、バイナリリバースエンジニアリング(秘密キーの取得を含む)に対して一定レベルの保護を提供する場合は、小さな(プロセス限定)暗号化VM(Dockerのような) 、 https://blogs.msdn.Microsoft.com/mvpawardprogram/2015/12/15/getting-started-with-net-and-docker/ )ベースのソリューション、Denuvo( https://www.denuvo.com/ )暗号化は顧客ごとに固有であり、マシンベースです。c#プログラムを(コンテナーのように機能する)c/c ++プログラムにカプセル化する必要があります。すべてのインメモリ暗号化-解読。

必要な投資と保証の種類に応じて、独自の戦略を実装できます。

プログラムがバックエンドプログラムである場合は、クライアント側に秘密鍵を保存し、バックエンド側に公開鍵を保存してローカルで解読するというすべての最善策(私が本当に推奨する唯一のもの)を選択できます。送信されるすべてのパスワードはしたがって、暗号化されます。パスワードとキーは、同じ目標を達成するための実際には異なる戦略であることに注意したい。つまり、パスワードを保存する代わりに、公開鍵を直接保存するほうがよいでしょう。

2
Soleil