SSL上的HSM私钥(SSL with private key on an HSM)

2019-07-31 11:51发布

我在我的应用程序的客户机 - 服务器架构,使用SSL。 目前,私人密钥存储在CAPI的密钥存储位置。 出于安全原因,我想存储在一个安全的地方的关键,理想的硬件签名模块(HSM)就是这个目的建造。 不幸的是,这种存储设备上的私钥,我无法弄清楚如何在我的应用程序中使用它。

在服务器上,我只是使用SslStream类和AuthenticateAsServer(...)调用。 此方法需要一个X509Certificate ,有它加载私钥对象,但因为私有密钥存储在一个安全的HSM(如非导出)的位置,我不知道如何做到这一点。

在客户端,我使用的是HttpWebRequest对象,然后使用ClientCertificates属性加我的客户端身份验证证书,但我在这里有同样的问题:我如何才能私钥?

我知道有一些硬件安全模块充当SSL加速器,但我并不真的需要一个加速器。 此外,这些产品往往有网络服务器,如IIS和Apache是​​哪个我不使用特殊的集成。

有任何想法吗? 我能想到的唯一的事情就是写我自己的SSL库,可以让我的手离开交易到HSM签订部分,但是这似乎是一个巨大的工作量。

Answer 1:

作为拉斯穆斯说你应该从你的HSM生产使用CSP。 检查此链接:

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

我成功地用一点点不同的方法在客户端上的客户端进行身份验证的HTTPS HttpWebRequestClientCertificates和智能卡。 在我的情况下,私有密钥存储在智能卡(类似于HSM)。 智能卡CSP然后使用PKCS#11签名,ENC /解密等,但这并不重要。 物业X509Certificate.Handle在SSL建立用于签名的客户端上的挑战,这个手柄包含有关证书的私钥信息。

在我的情况,我想以编程为智能卡设置引脚,以避免“输入PIN”从智能卡对话框中SSL创作的过程中,我也有这个功能做到了:

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\ProviderWin32是我对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
        );


Answer 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;

这应该工作。 请注意,如果您使用24而不是1提供商类型,这可能无法正常工作(它没有至少在默认CSP)。



Answer 3:

在HSM的我曾经使用过,这是不可见的。 有通常用于生成密钥对(用于生成证书请求或已完成的证书分发到更多的机器比,你生成的证书请求,这取决于它是什么样的HSM)的一个不同的过程,但一旦安装了证书在机器上,显示为一个带有私钥的正常证书,你只需要使用它,就像任何其他证件。



Answer 4:

取决于HSM的配置设置私钥被导出。 您需要发言的HSM供应商以找出他们的HSM的提供此功能。



Answer 5:

该HSM可以用CryptoAPI的CSP实现出货。 如果键正确映射到CryptoAPI中的证书,SslStream应该能够使用它而不导出。



文章来源: SSL with private key on an HSM
标签: .net ssl hsm