5

クライアントごとに 1 つの SecretKeys を生成するアプリケーションがあります。これらはデータベースに永続化する必要があります。私は一般的なセキュリティ パターンや実装にまったく慣れていないので、アドバイスを求めています。

KeyStore クラスは、特に SecretKeys を保護するために広く使用されているようです。ただし、データベースで KeyStore を使用することについてほとんど言及されていません。それが基本的な使用法である (したがって言及されていない) ためなのか、それともこれが悪いか冗長なアプローチであるからなのかを理解しようとしています。別のテクニックを使用しています。

基本的な設計は、各ユーザーが独自のキーストアを持ち、バイトへの変換によってデータベースに保存/ロードされることです (load() と store() を使用すると思います)。

これまでのデザインで何か問題がありましたか?また、KeyStore へのパスワードをどのように処理すればよいか考えています。すべてのキーストアに単一のパスワードのみを使用することを考えていますが、キーストアなしでこれを安全に保存するにはどうすればよいでしょうか?

これはバックエンド アプリで使用することを意図しており、クライアントがパスワードを私たちに転送することはなく、サーバー側にパスワードを提供する人間のオペレーターもいません。

4

2 に答える 2

5

現実の世界では、秘密鍵を安全に保管することが意図されている場合、秘密鍵はHSM安全に保管されます (数時間から数年の範囲)。このようなシステムとのインターフェースを支援するためのPKCS#11標準がありますが、控えめに言っても、ほとんどの HSM には HSM とインターフェースするための独自の優先メカニズムがあり、PKCS#11 インターフェースは通常、不自由なもの。

秘密鍵は、スマート カードや USB トークンなどの他のデバイスに安全に保存することもできますが、これはバックエンド システムの鍵ストレージではなく、大衆向けの鍵配布を目的としています。

ただし、誰もが HSM の予算を確保できるわけではなく、安全性の低い (そして明らかに安価な) 代替手段が多数使用されています。一部のシステム (Glassfish アプリケーション サーバーの場合を取り上げます) は、他のパスワードを保護するために使用されるマスター パスワードを保存します。同じことがキーにも当てはまります。他のキーを保護するために使用されるマスター キーがあります (ある意味で、これは HSM が内部で機能する方法に似ています)。もちろん、マスターキーを保護することで立ち往生しています。特定の環境では、システム管理者とアプリケーションだけに制限されたファイルにキーを配置できるため、これは簡単です。

免責事項:これは盲目的に摂取すべきアドバイスとして扱われるべきではありません:-)。キーをどうしても保護する必要がある場合は、HSM に投資してください。

于 2010-07-27T00:39:35.583 に答える
4

したがって、Java とキーストアを使用しています。

2 つの質問がありますが、正しく理解できましたか?:

1) アドバイスが欲しい

2)これをDBに保存する方法を知りたい

質問 1 への回答: Java を使用する場合、SSL を使用する必要があります。Java には、https を介して通信するクラスの実装が既にあり、SSL ハンドシェイクとすべてを実行します。必要なのは、 java.security.KeyStore をこの実装に提供することだけです。

基本的に、キーストアには次の 2 種類があります。

  • 1 つ目は、信頼するすべての証明書 (複数の証明書) を保存することです => Keystore.getInstance("JKS")

  • 2 つ目は、クライアント証明書 (1 つだけ) を秘密鍵と共に保持することです => Keystore.getInstance("PKCS12");

秘密鍵と証明書を作成する方法については、ここでは説明しません。私はあなたがすでにそこにいると仮定しています..(そうでない場合は、見つけることができます)。ただし、キーストアはパスワードで保護されています。したがって、誰もあなたのデータベースをハッキングできないのであれば、一般的には安全です。キーストアを開くためのパスワードを同じテーブルに保存する場合は、SQL インジェクションに注意してください。しかし、それが安全であると仮定しましょう。キーストアは、SSL ハンドシェークを処理する既存の実装を使用する機能を提供します。したがって、基本的にキーストアを使用することは悪いことではありません。ところで、相互認証が必要な場合にのみ PKCS12 キーストアを使用することに注意してください (つまり、自分自身を識別する必要もあります)。

質問 2 への回答: はい、データベースにキーストアを格納できますが、少し注意が必要です。キーストアでは、ストア メソッドとロード メソッドしか使用できないためです。しかし、あなたは次のようにこれを達成することができます:

@Entity
public class MyKeyStoreClass {
private Long id;
@Transient
private KeyStore keystore;
private String passwordForKeyStore;
private Byte[] keyStoreAsBytes;

@PreUpdate
@PrePersist
public void concertKeyStoreToBytes() {
   ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        keystore.store(byteArrayOutputStream,
                passwordForKeyStore.toCharArray());
   keyStoreAsBytes = byteArrayOutputStream.toByteArray();
}

@PostLoad
public void getKeyStore() {
   if (keystore == null && keyStoreAsBytes != null) {
      keyStore = KeyStore.getInstance(getKeystoreType().getType());
      keyStore.load(new ByteArrayInputStream(keystoreAsBytes), passwordForKeyStore.toCharArray()); 
   }    
}

上記のコードは、私がここ (エディターなし) で書いたので、おそらく 100% 正しいとは限りません。しかし、それは一般的にあなたがそれを行う方法です.私は以前にそれを行ったことがあり、うまくいきました;)私のSpring構成は、永続化または更新の前または後に注釈付きのメソッドを実行することに注意してください. 注釈とスプリングを使用しない場合は、別の方法でこれを実現できます..

于 2013-03-08T09:57:21.513 に答える