0

クライアント マシンでデータに署名して暗号化する必要があります。その後、SFTP を使用してファイルをサーバー マシンに送信します。サーバー上で署名を検証し、データを復号化したい。

このスキームは安全ですか? セキュリティを向上させるにはどうすればよいですか?

次の手順を実行しています。

  1. Java キーストアの作成。
  2. 自己署名 X509 v3 証明書を作成し、JKS キーストアに挿入します。
  3. この JKS キーストアをクライアントとサーバーの両方に提供します。
  4. 署名データ : JKS キーストアからプライベート キーと証明書を取得し、 and を使用してデータに署名しCMSSignedDataGeneratorますCMSSignedData
  5. を使用して、前のステップの署名付きバイトを暗号化しCMSEnvelopedDataGeneratorます。

サーバー側では、次の手順を実行します。

  1. JKS をロードします。
  2. JKS から秘密鍵を取得します。
  3. CMSEnvelopedData を取得してコンテンツを取得します。
  4. X509 証明書をロードし、CMSSignedData を使用して署名を検証し、データを復元します。

公開鍵と秘密鍵のペアは 1 つしかありません。Bouncy Castle と PKCS 7 を使用しています。


JKSの作成:

public static KeyStore createKeyStore() throws Exception {
         KeyStore keyStore = KeyStore.getInstance("JKS");
         keyStore.load(null, null);

    X500PrivateCredential rootCredential = createRootCredential();
    X500PrivateCredential interCredential = createIntermediateCredential(
            rootCredential.getPrivateKey(), rootCredential.getCertificate());
    X500PrivateCredential endCredential = createEndEntityCredential(
            interCredential.getPrivateKey(),
            interCredential.getCertificate());

    keyStore.setCertificateEntry(rootCredential.getAlias(),
            rootCredential.getCertificate());
    keyStore.setKeyEntry(
            endCredential.getAlias(),
            endCredential.getPrivateKey(),
            ConfigurationClass.PRIVATE_KEY_PASSWORD.toCharArray(),
            new Certificate[]{endCredential.getCertificate(),
                interCredential.getCertificate(),
                rootCredential.getCertificate()});

    keyStore.store(new FileOutputStream(ConfigurationClass.JAVA_KEY_STORE_PATH), ConfigurationClass.KEY_STORE_PASSWORD.toCharArray());
    return keyStore;
}
4

2 に答える 2

2

これをしないでください。SFTP経由でデータを転送するだけですが、認証には証明書(サーバーによって発行されたもの)を使用します。この投稿によると、これはJSch ライブラリで実行できます。

データを送信する直前に暗号化し、その後すぐに復号化する場合、保管中のデータのセキュリティではなく、トランスポートのセキュリティを行います。

良いプリミティブから組み立てているとしても、独自の暗号を展開することは悪いことであり、一般的には失敗します。あなたがしていることの場合、少なくとも2つの問題があります。

  1. パディングオラクル攻撃などを防ぐために、暗号化されたデータを暗号化してから署名する必要があります
  2. 鍵の管理に問題が生じる可能性があります。

    1. 入ってくる新しいクライアントにどのように対処しますか?
    2. 攻撃者が自分のキーをサーバーに追加するのを防ぐものは何ですか?

      これはばかげた質問のように思えるかもしれませんが、実際には、サーバー キーを提供する外部サービスがある場合、サーバーはそのサービスをどのように認証するのでしょうか? 正しい方法は、サーバーに、その (自己署名された) 「ルート」権限の下で署名されたキーを発行させることです (これは、あなたが持っている他の信頼できるサーバーでもかまいません)。

于 2012-08-22T15:02:00.973 に答える
1

あなたが説明していることは確かに安全ではありません。秘密鍵は移動しないでください。キーペアは通常、必要な場所で生成されます。

必要なのは、自己署名証明書を使用して、ある種のインフラストラクチャCAを作成することです。このための秘密鍵は非常に安全に保管する必要があります(実際には、秘密鍵は他の証明書に署名するためにのみ必要であるため、文字通り金庫に保管することができます)。

ここで、クライアントとサーバーの両方で2つのキーペアと2つの証明書要求を生成します。両方の証明書要求をインフラストラクチャCAに送信します。このCAは、要求に署名(およびデータを追加)して、証明書を生成する必要があります。証明書はクライアントとサーバーに送信され、独自の(パスワードで保護された)JKSストアに追加されます。

データを送信するには、サーバーの公開鍵で暗号化してから、クライアントの秘密鍵で署名する必要があります。サーバーは、最初にクライアントの署名を確認してから、独自の秘密鍵を使用して復号化する必要があります。そうしないと、オラクルの攻撃を埋めることができます。このためには、証明書チェーンを検証するためのCA証明書が必要です。

続行する前に、PKIについてできるだけ理解してください。また、スキームは秘密鍵(したがってJKSパスワード)と同じくらい安全であることを忘れないでください。私が説明したのは一般的な構造だけであり、実装の詳細がたくさんあります。

注:SFTPも拡張しなかったため、無視しました。厳密に言えば、あなたはそれを必要としないはずです。

于 2012-08-26T00:04:00.920 に答える