web-dev-qa-db-ja.com

秘密鍵はどこに保存しますか?

ソフトウェアの一部を暗号化したいとします。たとえば、データベースの資格情報などです。これらの値をどこかに保存する必要がありますが、クリアテキストで保存すると、攻撃者が不正にアクセスしやすくなります。

ただし、クリアテキストを暗号化する場合、どこにキーを保存すればよいですか?ソフトウェアがアクセスできるものはすべて、難読化のレベルに関係なく、断固とした攻撃者がアクセスできます。

  • キーがファイルシステムのセキュリティモデルによって保護されているとしましょう。しかし、(悪意のある)スーパーユーザー、またはそのような忠実度を提供しないプラットフォームについてはどうでしょうか?
  • または、キーはソフトウェアバイナリにハードコードされていますが、常に逆コンパイルされる可能性があり、オープンソースソフトウェアやインタープリターコードについてはどうでしょうか。
  • キーが生成される場合、そのようなアルゴリズムは決定論的(おそらく)である必要があり、同じ問題がシードに適用されます。
  • 等.

暗号化はそのチェーンの最も弱いリンクと同じくらい強力であり、これはかなり緩いもののようです!それが仕事に適切なツールであると仮定すると(私を笑わせる)、そのような情報をどのようにして堅牢に保護できますか?


仕事に適したツールについて:おそらく、たとえば-サービスアクセス(DB、認証サーバーなど)の場合、サービスアカウントを使用してこの層でのアクセスを制限します。監査など、資格情報をクリアテキストで保持することはそれほど心配ではありません。

しかし、私にはそれでも不十分だと思われます。本来あるべきではない場所をぶらぶらしてほしくないのです。

23
Xophmeister

まず、私は自分をセキュリティの専門家とは言いませんが、私はこの質問に答えなければならない立場にあります。私が発見したことは私を少し驚かせました:完全に安全なシステムのようなものはありません。まあ、完全に安全なシステムはサーバーがすべてオフになっているものだと思います:)

当時私と一緒に働いていた誰かが、侵入者に対してレベルを上げるの観点から安全なシステムを設計することを説明しました。したがって、セキュリティ保護の各層は、攻撃の機会を減らします。

たとえば、秘密鍵を完全に保護できたとしても、システムは完全に安全ではありません。ただし、セキュリティアルゴリズムを正しく使用し、パッチを適用して最新の状態にすると、障害が発生します。しかし、はい、十分に強力で十分な時間を与えられたスーパーコンピュータは暗号化を破ることができます。これはすべて理解されていると思いますので、質問に戻ります。

質問は明確ですので、まず各ポイントに取り組みます。

キーがファイルシステムのセキュリティモデルによって保護されているとしましょう。しかし、(悪意のある)スーパーユーザー、またはそのような忠実度を提供しないプラットフォームについてはどうでしょうか?

はい。 Windows Key Store またはパスワードで暗号化されたTLS秘密鍵のようなものを使用すると、秘密鍵へのパスワード(またはアクセス)を持つユーザーに公開されます。しかし、私はあなたが基準を上げることに同意するだろうと思います。ファイルシステムACL(適切に実装されている場合)は、かなり良いレベルの保護を提供します。そして、あなたは個人的にスーパーユーザーを精査し、知る立場にあります。

または、キーはソフトウェアバイナリにハードコードされていますが、常に逆コンパイルされる可能性があり、オープンソースソフトウェアやインタープリターコードについてはどうでしょうか。

はい、ハードコードされたキーをバイナリで見ました。繰り返しになりますが、これは少しレベルを引き上げます。このシステムを攻撃する人(Javaの場合)は、Javaがバイトコード(など)を生成することを理解し、それを逆コンパイルする方法を理解する必要があります。それを読み取る必要があります。直接書き込む言語を使用している場合マシンコードを見ると、これによりレベルが少し高くなっていることがわかります。これは理想的なセキュリティソリューションではありませんが、ある程度の保護を提供できます。

キーが生成される場合、そのようなアルゴリズムは決定論的(おそらく)である必要があり、同じ問題がシードに適用されます。

はい。基本的に、アルゴリズムは秘密鍵を作成するための秘密鍵情報になります。したがって、今は保護する必要があります。

したがって、セキュリティポリシーkey managementのコア問題を特定したと思います。安全なシステムを提供するには、キー管理ポリシーを適切に設定することが重要です。そして、それは かなり広いトピック です。

では、問題は、システム(および、したがって秘密鍵)をどの程度安全にする必要があるかということです。あなたのシステムでは、基準をどのくらい高くする必要がありますか?

さて、あなたが支払う意思があるなら、これに対する解決策を生み出す人々がいます。最終的に HSM(ハードウェアセキュリティモジュール) を使用しました。これは基本的に、ハードウェアにキーを含む改ざん防止サーバーです。このキーを使用して、暗号化に使用される他のキーを作成できます。ここでの考え方は、(正しく構成されていれば)キーnever Leave HSMです。 HSMのコストたくさん。しかし、一部の企業(クレジットカードデータの保護など)では、違反のコストははるかに高くなります。したがって、バランスがあります。

多くのHSMは、機能のメンテナンスと管理からのキーカードを使用します。キーを変更するには、定足数のキーカード(9つのうち5つは言う)を物理的にサーバーに配置する必要があります。したがって、これは、スーパーユーザーの定足数が共謀した場合にのみ違反を許可することで、基準をかなり高くします。

HSMと同様の機能を提供するソフトウェアソリューションが世の中にあるかもしれませんが、私はそれらが何であるかを知りません。

これが質問への回答に役立つことはわかっていますが、これが役立つことを願っています。

26
Davin Tryon

あなたがしたいことはできません。

キーがファイルシステムのセキュリティモデルによって保護されているとしましょう。しかし、(悪意のある)スーパーユーザー、またはそのような忠実度を提供しないプラットフォームについてはどうでしょうか?

基本的に、悪意のあるユーザーからの保護が必要です。モデルでは、ある時点で誰かがキーにアクセスできるようになります。その人が悪意のある場合はどうなりますか?あなたが悪意のある場合はどうなりますか?参照してください、あなたが述べた問題は、キーがないことを除いて解決できません。

したがって、データベース資格情報ではなく、他の認証メカニズムを使用してください。しかし、何があっても、ある時点で誰かがデータにアクセスする必要があり、誰かが悪意を持つ可能性があります。

2
Pieter B

これは、作成されたのと同じレベルでは実際に解決できない問題の1つです。私たちはいくつかの基本的な哲学に一歩戻り、解決を期待してカスケードに従う必要があります。

最初の哲学は「決してクライアントを信頼しない」であり、密接に関連する「本当に秘密を守りたい場合は、誰にも言わないでください!」

簡単な例は、あなたが言及したように、データベースの資格情報です。明らかに、あなたはあなたのクライアントがそれにアクセスできるようにしたいが、ランダムなインターネットの見知らぬ人にはアクセスさせたくないので、ある種の身元/検証/ログインシステムが必要です。しかし、これを隠すことの核となる前提は問題です。ユーザー自身がシークレットを所有している必要があるが、そのシークレットが何であるかをユーザーに知られたくない場合は、それを非表示にするか、開けないようにするだけです。秘密のパッケージ」。しかし、彼らはまだそれを見つけることができるので、あなたはバックアップ計画を持っているほうがいいです!

最も簡単な解決策は、「それを行わないこと」です。ユーザー自身のアカウント資格情報を使用して、ソフトウェアのデータベースへのクライアントレベルのアクセスを許可します。それだけです。クライアントが悪意のあるものになった場合、最悪のシナリオは、クライアントが自分のデータを台無しにする可能性があることです。それでおしまい。データベースとシステムには、最大で、そのクライアントからのジャンクエントリが含まれているはずです。そのクライアントのみを対象とし、他の誰か(あなたを含む)が騒乱に苦しむことはありません。

展開されたソフトウェアに何かを実行させたいだけで、世界中の誰もが接続して同じことを実行できないようにする特定のユースケースがありますが、そのためには秘密を隠しているだけであり、それを行う唯一の正当な理由は頭痛やシステム活動を減らします。あなたの隠された情報が一般的な知識になった場合、それはゲームを壊すのではなく、最悪の迷惑である方がよいでしょう。

これらの狭いユースケースの1つである場合、それは難読化に関するものであり、それはすべて創造性を得ることに関するものです。それはコードゴルフによく似ています。ただし、パズルを作成するのはあなたです。それが本当にすべてです-パズル。そして、人々はパズルを解くのが好きなので、繰り返しますが、誰かがそれを理解したときは大丈夫です。

しかし、世界のほとんどの場合、ユーザーから秘密fromを守る必要を心配せずに操作するのが最善です。代わりに、ベストプラクティスは、ユーザーにシークレットを許可し、ユーザーを保護する責任を負わせて(たとえば、ユーザー名とパスワード)、シークレットが漏洩したり悪用されたりした場合に発生するリスクを制限することです。

真の「キー管理」暗号化/セキュリティコンテキストでは、「秘密キーを保存する場所」の答えは「他のどこか!」です。暗号化はポイントツーポイントの保護であり、公開鍵と秘密鍵の暗号化は、送信中の情報を時間と空間で保護するように設計されています。秘密鍵は本質的に脆弱であり、それを保護することは実際には暗号化の重複の問題ではありません-それは完全にアクセスからそれを保護しています。システムがそれにアクセスする必要がある場合は、システム自体を保護する必要があります。クライアントのマシンではこれを行うことはできません。彼らはいつでもVMを実行し、RAMをダンプし、ネットワークトラフィックを傍受し、プロキシまたは仮想NICをインストールし、実行可能ファイルを逆コンパイルできます...その緩やかな戦いに自発的に関与しないでください。

DRMのような何かをする必要がある場合、シークレットを格納する必要性が実際にはソフトウェア自体の使用を制御することに基づいている場合は、 それはまったく別の状況です です。


TLDR:ユーザーの秘密を保持せず、ユーザーの秘密を保持します

2
BrianH

私が現在使用しているシステムの1つは、このように動作します。

  • 認証サービスのログインフォームから始めます。 2要素認証を使用して、私が主張するとおりの人物であることを確認します。
  • 保護されたサービスへのアクセスに使用できる一時的なSSL証明書を受け取ります。サービスは、受け入れる証明書を追跡します。
  • 私の交換は盗聴からのこの証明書によって暗号化されています。期限切れになるため、クラックしようとしてもあまり役に立ちません。
  • 証明書はすぐに(数時間で)期限切れになりますが、それほど速くはないので、すべてのやり取りにパスワードを入力する必要はありません。
  • 証明書は、反対側で即座に取り消すことができます。

もちろん、保護されたサービスは私の手の届かないところにあります。別のアカウントの下で(そしておそらくコンテナー内で)自分のマシンで実行できますが、スーパーユーザー特権を持っているため、制限を回避しようとする可能性があります。

基本的に、悪意のあるスーパーユーザーがいる場合、すべての賭けは無効になります。そして、あなたはすべき脅威モデルに悪意のあるスーパーユーザーがいると想定します。

したがって、保護されたサービスをクライアントからアクセス可能なマシンから分離する必要があります。保護されたサービスを、ネットワーク経由でのみアクセス可能なマシンに移動します。クライアントを仮想マシンに配置して、保護されたサービスが実行されている残りの物理マシンに到達できないようにします。

保護されたサービスがそのような対策を講じることができるほど貴重ではない場合は、OSが提供する暗号化されたキーストアを使用してください。Windows、Linux、OSXの両方にキーリング実装があります。

1
9000