3

私のアプリケーションには、SSL を使用するクライアント/サーバー アーキテクチャがあります。現在、秘密鍵は CAPI のキー ストアの場所に格納されています。セキュリティ上の理由から、キーをより安全な場所、理想的にはこの目的のために構築されたハードウェア署名モジュール (HSM) に保存したいと考えています。残念ながら、そのようなデバイスに秘密鍵が保存されているため、アプリケーションでそれを使用する方法がわかりません。

サーバーでは、SslStreamクラスとAuthenticateAsServer(...)呼び出しを使用しているだけです。このメソッドはX509Certificate、秘密鍵がロードされたオブジェクトを取得しますが、秘密鍵は HSM 上の安全な場所 ​​(エクスポートできない場所など) に格納されているため、これを行う方法がわかりません。

クライアントでは、HttpWebRequestオブジェクトを使用し、ClientCertificatesプロパティを使用してクライアント認証証明書を追加していますが、ここでも同じ問題があります。秘密鍵を取得するにはどうすればよいですか?

SSL アクセラレータとして機能する HSM がいくつかあることは知っていますが、実際にはアクセラレータは必要ありません。また、これらの製品は、私が使用していない IIS や Apache などの Web サーバーと特別に統合される傾向があります。

何か案は?私が考えられる唯一のことは、トランザクションの署名部分を HSM に渡すことができる独自の SSL ライブラリを作成することですが、これは膨大な量の作業のように思えます。

4

5 に答える 5

7

Rasmus が述べたように、HSM プロデューサーの CSP を使用する必要があります。このリンクを確認してください:

http://forums.asp.net/t/1531893.aspx

HttpWebRequestClientCertificatesおよびスマート カードを使用したクライアント認証 HTTPS に対して、クライアントで少し異なるアプローチを使用することに成功しました。私の場合、秘密鍵はスマート カードに保存されます (HSM と同様)。スマート カード CSP は、署名、暗号化/復号化などに PKCS#11 を使用しますが、これは重要ではありません。プロパティX509Certificate.Handleは、クライアントでチャレンジに署名するために SSL 確立で使用され、このハンドルには証明書の秘密鍵に関する情報が含まれます。

私の場合、SSL作成の過程でスマートカードからの「PINの入力」ダイアログを避けるために、プログラムでスマートカードのピンを設定したかったので、この機能でそれを行いました:

public void SetContext(X509Certificate2 cert)
{
        IntPtr p = IntPtr.Zero;
        bool result = Win32.CryptAcquireContext(ref p, "keyContainer", "Siemens Card API CSP", 1, 0);
        byte[] pin = new ASCIIEncoding().GetBytes("0000");
        result = Win32.CryptSetProvParam(p, 32, pin, 0);
        result = Win32.CertSetCertificateContextProperty(cert.Handle, 1, 0, p);
}

インストールされているすべての CSP の名前は、 にありHKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Cryptography\Defaults\Providerます。Win32は C++/C# 相互運用のための私のクラスで、次のようになります。

[DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
    public static extern bool CryptAcquireContext(
        ref IntPtr hProv,
        string pszContainer,
        string pszProvider,
        uint dwProvType,
        uint dwFlags
        );
[DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Auto)]
    public static extern bool CryptSetProvParam(
        IntPtr hProv,
        uint dwParam,
        [In] byte[] pbData,
        uint dwFlags);
[DllImport("CRYPT32.DLL")]
    internal static extern Boolean CertSetCertificateContextProperty(
        IntPtr pCertContext,
        uint dwPropId,
        uint dwFlags,
        IntPtr pvData
        );
于 2010-09-24T12:02:10.733 に答える
2

HSM に CAPI CSP が付属している場合、以下を実行できます。

var certificate = new X509Certificate2(pathToPublicCert);

var cspParameters = new CspParameters()
{
   ProviderType = 1, /* Use 1 instead of 24 (the default) */
   ProivderName = "My HSM Cryptographic Provider Name",
   KeyContainerName = "My Private Key Container Name",
   KeyNumber = 1, /* Key exchange key */
   Flags = CspProviderFlags.UseExistingKey | CspProviderFlags.UseNonExportableKey,
};

var privateKey = new RSACryptoServiceProvider(cspParameters);

certificate.PrivateKey = privateKey;

これはうまくいくはずです。プロバイダー タイプに 1 ではなく 24 を使用すると、これが機能しない可能性があることに注意してください (少なくとも既定の CSP では機能しません)。

于 2011-01-31T00:29:01.707 に答える
0

HSMには、CryptoAPICSP実装が付属している場合があります。キーがCryptoAPIの証明書に適切にマップされている場合、SslStreamはそれをエクスポートせずに使用できるはずです。

于 2009-09-09T14:05:58.250 に答える
0

私が使用したHSMでは、これはあなたから隠されています。通常、キーペアを生成するプロセスは異なります(証明書要求を生成するため、または完成した証明書を、証明書要求を生成した場所よりも多くのマシンに配布するために、HSMの種類に応じて)が、証明書がインストールされるとマシン上では、秘密鍵を使用した通常の証明書として表示され、他の証明書と同じように使用できます。

于 2009-08-05T18:44:19.840 に答える
0

秘密鍵は、HSM の構成設定に応じてエクスポートされます。どの HSM がこの機能を提供しているかを確認するには、HSM ベンダーに問い合わせる必要があります。

于 2009-08-24T10:01:10.260 に答える