.net - 在 HSM 上使用私钥的 SSL

标签 .net ssl hsm

我的应用程序中有一个使用 SSL 的客户端-服务器架构。目前,私钥存储在 CAPI 的 key 存储位置。出于安全原因,我想将 key 存储在更安全的地方,最好是为此目的构建的硬件签名模块 (HSM)。不幸的是,私钥存储在这样的设备上,我不知道如何在我的应用程序中使用它。

在服务器上,我只是使用 SslStream 类和 AuthenticateAsServer(...) 调用。此方法采用加载了私钥的 X509Certificate 对象,但由于私钥存储在 HSM 上的安全(例如不可导出)位置,我不知道如何执行此操作。

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

我知道有一些 HSM 可以充当 SSL 加速器,但我真的不需要加速器。此外,这些产品往往与我没有使用的 IIS 和 Apache 等 Web 服务器进行特殊集成。

有什么想法吗?我唯一能想到的就是编写我自己的 SSL 库,它允许我将交易的签名部分交给 HSM,但这似乎是一项巨大的工作。

最佳答案

正如 Rasmus 所说,您应该使用 HSM 生产商提供的 CSP。检查此链接:

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

我在客户端成功地使用了一些不同的方法来使用 HttpWebRequestClientCertificates 和智能卡进行客户端身份验证的 HTTPS。在我的例子中,私钥存储在智能卡中(类似于 HSM)。智能卡 CSP 然后使用 PKCS#11 进行签名、加密/解密等,但这并不重要。属性 X509Certificate.Handle 在 SSL 建立中用于在客户端签署质询,此句柄包含有关证书私钥的信息。

在我的例子中,我想以编程方式为智能卡设置 PIN,以避免在 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);
}

您可以在 HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Cryptography\Defaults\Provider 中找到所有已安装 CSP 的名称。 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
        );

关于.net - 在 HSM 上使用私钥的 SSL,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1234938/

相关文章:

c# - C#中的正则表达式问题

c# - 如何在不在 C# Windows 应用程序中创建父类的新实例的情况下返回父窗体

安装 SSL 证书时 Tomcat 没有响应

php - 如何在 PHP 中使用 Doctrine2 设置 SSL 加密的 MySQL 连接(不是 Symfony,不是 Doctrine1)

c - 无法编译读取智能卡的 C 应用程序

c# - 在您的应用程序中加载任何页面时是否有调用的函数?

c# - 无法加载 .NET 程序集

amazon-ec2 - 如何在 Ubuntu 18.04 TLS 上安装 AWS CloudHSM? (需要 libjson-c2,但只有 libjson-c3 可用)

node.js - 使用 mocha/superagent 测试本地 https 服务器

pkcs#11 - 从一个 HSM 客户端创建的 key 不可在另一客户端中使用