SSL with private key on an HSM

╄→尐↘猪︶ㄣ 提交于 2019-12-06 10:43:08

问题


I have a client-server architecture in my application that uses SSL. Currently, the private key is stored in CAPI's key store location. For security reasons, I'd like to store the key in a safer place, ideally a hardware signing module (HSM) that is built for this purpose. Unfortunately, with the private key stored on such a device, I can't figure out how to use it in my application.

On the server, I am simply using the SslStream class and the AuthenticateAsServer(...) call. This method takes an X509Certificate object that has its private key loaded, but since the private key is stored in a secure (e.g. non exportable) location on the HSM, I don't know how to do this.

On the client, I am using an HttpWebRequest object and then using the ClientCertificates property to add my client authentication certificate, but I have the same problem here: how do I get the private key?

I know there are some HSMs that act as SSL accelerators but I don't really need an accelerator. Also, these products tend to have special integration with web servers such as IIS and Apache which I'm not using.

Any ideas? The only thing I can think of would be to write my own SSL library that would allow me to hand off the signing portion of the transaction to the HSM, but this seems like a huge amount of work.


回答1:


As Rasmus stated you should use CSP from your HSM producer. Check this link:

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

I successfully used a little bit different approach on the client for client-authenticated HTTPS with HttpWebRequest, ClientCertificates and smart card. In my case private key is stored in the smart card (similar to HSM). Smart card CSP then uses PKCS#11 for signing, enc/decrypt etc, but that is not important. Property X509Certificate.Handle is used in SSL establishment for signing the challenge on the client and this handle contains information about certificate's private key.

In my case I wanted to set pin programatically for smart card to avoid "Enter PIN" dialog from smart card in process of SSL creation, and I've done it with this function:

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);
}

You can find names of all installed CSPs in HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Cryptography\Defaults\Provider. Win32 is my class for C++/C# interop and looks like this:

[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
        );



回答2:


If the HSM comes with CAPI CSP with can do the following:

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;

This should work. Note that if you use 24 instead of 1 for provider type this might not work (it does not at least for the default CSP).




回答3:


In the HSMs I've worked with, this is hidden from you. There's typically a different process for generating the key pairs (either for generating the certificate request or for distributing the completed certificate to more machines than where you generated the certificate request, depending on what kind of HSM it is), but once the certificate is installed on the machine, it appears as a normal certificate with a private key, and you just use it as you would any other certificate.




回答4:


Private keys are exported depending on the configuration settings of the HSM. You need to speak to the HSM vendor to find out which of their HSM's provide this feature.




回答5:


The HSM may ship with a CryptoAPI CSP implementation. If the key is properly mapped to the certificate in CryptoAPI, the SslStream should be able to use it without exporting it.



来源:https://stackoverflow.com/questions/1234938/ssl-with-private-key-on-an-hsm

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!