認証資格情報を保存する理由は大きく異なりますが、次の 2 つがあります。
- ユーザーを認証するには: たとえば、ユーザーがプログラムに対して認証された後にのみ、サービスへのユーザー アクセスを許可します。
- 別のプログラムまたはサービスでプログラムを認証するには: たとえば、ユーザーがプログラムを起動すると、IMAP を使用してインターネット経由でユーザーの電子メールにアクセスします。
最初のケースでは、パスワード (またはパスワードの暗号化バージョン) を保存しないでください。代わりに、パスワードを高品質のソルトでハッシュし、使用するハッシュ アルゴリズムが (辞書攻撃を防ぐため) PBKDF2 や bcrypt などの計算コストが高いことを確認する必要があります。詳細については、 Salted Password Hashing - Doing it Rightを参照してください。このアプローチに従うと、ハッカーがソルト化された低速ハッシュ化されたトークンを取得したとしても、それを使用して多くのことを行うことはできません.
2番目のケースでは、秘密の発見をより困難にするために行われたことがいくつかあります(質問で概説しているように)。
- 必要になるまでシークレットを暗号化しておき、必要に応じて復号化し、その後すぐに再暗号化する
- アドレス空間のランダム化を使用して、アプリケーションが実行されるたびにキーが異なるアドレスに保存されるようにします
- OS キーストアの使用
- Java や Python などの VM ベースの内省的言語ではなく、C/C++ などの「難しい」言語を使用する
そのようなアプローチは確かに何もないよりはましですが、熟練したハッカーは遅かれ早かれそれを破るでしょう.
トークン
理論的な観点から言えば、認証とは、チャレンジされた人物が本人であることを証明する行為です。伝統的に、これは共有シークレット (パスワード) で達成されますが、次のような他の方法で自分自身を証明できます。
- 帯域外認証。たとえば、私が住んでいる場所では、インターネット バンクにログインしようとすると、携帯電話に SMS としてワンタイム パスワード(OTP) が届きます。この方法では、特定の電話番号を所有していることを証明します。
- セキュリティ トークン: サービスにログインするには、トークンのボタンを押して OTP を取得し、それをパスワードとして使用する必要があります。
他のデバイス:
そして、より完全なリストはこちら
これらすべてのアプローチの共通点は、エンドユーザーがこれらのデバイスを制御し、シークレットが実際にトークン/カード/電話から離れることはなく、プログラムに保存されることもないことです。これにより、より安全になります。
セッション盗用
ただし(ただし、常にあります):
ハッカーがセキュリティ トークンにアクセスできないようにログインを保護したとします。これで、アプリケーションは保護されたサービスと問題なくやり取りできるようになりました。残念ながら、ハッカーがコンピューターで任意の実行可能ファイルを実行できる場合、ハッカーは、たとえば、サービスの有効な使用に追加のコマンドを挿入することにより、セッションを乗っ取ることができます. つまり、パスワードを保護しても、ハッカーは「保護された」リソースに引き続きアクセスできるため、パスワードはまったく関係ありません。
複数のクロスサイト スクリプティング攻撃が示すように、これは非常に現実的な脅威です (一例として、US Bank と Bank of America の Web サイトが脆弱ですが、他にも数え切れないほどあります)。
安全なプロキシ
前述のように、アプリケーションがログオンできるように、サードパーティのサービスまたはシステムにアカウントの資格情報を保持することには根本的な問題があります。特に、唯一のログオン方法がユーザー名とパスワードである場合です。
これを部分的に軽減する 1 つの方法は、サービスへの通信を安全なプロキシに委任し、アプリケーションとプロキシ間の安全なサインオン アプローチを開発することです。このアプローチでは
- アプリケーションは PKI スキームまたは 2 要素認証を使用してセキュア プロキシにサインオンします
- ユーザーは、サードパーティ システムのセキュリティ資格情報をセキュア プロキシに追加します。資格情報がアプリケーションに保存されることはありません
- その後、アプリケーションがサードパーティ システムにアクセスする必要がある場合、アプリケーションはプロキシにリクエストを送信します。プロキシは、セキュリティ資格情報を使用してログオンし、要求を行い、結果をアプリケーションに返します。
このアプローチの欠点は次のとおりです。
- ユーザーは、クレデンシャルのストレージでセキュア プロキシを信頼したくない場合があります。
- ユーザーは、セキュア プロキシを介してサードパーティ アプリケーションにデータが流れることを信頼していない可能性があります。
- アプリケーションの所有者には、プロキシを実行するための追加のインフラストラクチャとホスティングのコストがかかります
いくつかの答え
したがって、具体的な答えに進みます:
Pythonを使用して認証資格情報を安全に保存するにはどうすればよいですか?
- アプリケーションがユーザーを認証するためのパスワードを保存する場合は、 https: //www.dlitz.net/software/python-pbkdf2/ などの PBKDF2 アルゴリズムを使用します。
- 別のサービスにアクセスするためのパスワード/セキュリティ トークンを保存する場合、完全に安全な方法はありません。
- ただし、pyscardなどを使用して、認証戦略をスマートカードなどに切り替えることを検討してください。スマートカードを使用して、アプリケーションに対してユーザーを認証することも、X.509 証明書を使用して別のサービスに対してアプリケーションを安全に認証することもできます。
「すべてが公開されている」という言語の哲学について何かできることはありますか? 「私たちは皆、ここでは大人として同意している」ことは知っていますが、パスワードを攻撃者と共有するか、別の言語を使用するかの選択を迫られるべきでしょうか?
私見では、Python で特定のモジュールを作成することに何の問題もありません。このモジュールは、秘密情報を隠すのが最も厄介であり、他の人が再利用するのに適したバグになります (他のプログラマーを苛立たせることが目的です)。大部分を C でコーディングしてリンクすることもできます。ただし、明らかな理由から、他のモジュールに対してはこれを行わないでください。
ただし、最終的には、ハッカーがコンピューターを制御できる場合、コンピューターのプライバシーはまったくなくなります。理論上の最悪のケースは、プログラムが VM で実行されており、ハッカーがコンピュータ上のすべてのメモリ (BIOS やグラフィックス カードを含む) に完全にアクセスでき、アプリケーションを認証してその秘密を発見できるというものです。
絶対的なプライバシーがない場合、残りは単なる難読化であり、保護のレベルは単純に難読化の難しさと熟練したハッカーがどれだけ情報を欲しがっているかです。カスタム ハードウェアや10 億ドル規模の製品であっても、それがどのように終わるかは誰もが知っています。
Python キーリングの使用
これにより、他のアプリケーションに対してキーが非常に安全に管理されますが、すべての Python アプリケーションがトークンへのアクセスを共有します。これは、心配しているタイプの攻撃に対して少しでも安全ではありません。