SSL с закрытым ключом на HSM - PullRequest
       17

SSL с закрытым ключом на HSM

2 голосов
/ 05 августа 2009

В моем приложении есть клиент-серверная архитектура, использующая SSL. В настоящее время закрытый ключ хранится в хранилище ключей CAPI. Из соображений безопасности я хотел бы хранить ключ в более безопасном месте, в идеале - аппаратный модуль подписи (HSM), созданный для этой цели. К сожалению, с закрытым ключом, хранящимся на таком устройстве, я не могу понять, как использовать его в моем приложении.

На сервере я просто использую класс SslStream и вызов AuthenticateAsServer(...). Этот метод принимает объект X509Certificate, в который загружен его закрытый ключ, но поскольку закрытый ключ хранится в безопасном (например, не экспортируемом) месте на HSM, я не знаю, как это сделать.

На клиенте я использую объект HttpWebRequest, а затем использую свойство ClientCertificates для добавления сертификата проверки подлинности клиента, но у меня возникает та же проблема: как получить закрытый ключ?

Я знаю, что есть некоторые HSM, которые действуют как ускорители SSL, но мне не нужен ускоритель. Кроме того, эти продукты, как правило, имеют специальную интеграцию с веб-серверами, такими как IIS и Apache, которые я не использую.

Есть идеи? Единственное, о чем я могу думать, - это написать собственную библиотеку SSL, которая позволила бы мне передать часть подписи транзакции в HSM, но это похоже на огромный объем работы.

Ответы [ 5 ]

3 голосов
/ 24 сентября 2010

Как сказал Расмус, вам следует использовать CSP от вашего производителя HSM. Проверьте эту ссылку:

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

Я успешно использовал немного другой подход на клиенте для аутентифицированного клиента HTTPS с HttpWebRequest, ClientCertificates и смарт-картой. В моем случае закрытый ключ хранится на смарт-карте (аналогично HSM). Затем CSP смарт-карты использует PKCS # 11 для подписи, шифрования / дешифрования и т. Д., Но это не важно. Свойство 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\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
        );
2 голосов
/ 31 января 2011

Если 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 по умолчанию).

0 голосов
/ 24 августа 2009

Закрытые ключи экспортируются в зависимости от настроек конфигурации HSM. Вам нужно поговорить с поставщиком HSM, чтобы узнать, какие из его HSM предоставляют эту функцию.

0 голосов
/ 09 сентября 2009

HSM может поставляться с реализацией CryptoAPI CSP. Если ключ правильно сопоставлен с сертификатом в CryptoAPI, SslStream сможет использовать его без экспорта.

0 голосов
/ 05 августа 2009

В HSM, с которыми я работал, это скрыто от вас. Обычно существует другой процесс для генерации пар ключей (либо для генерации запроса сертификата, либо для распространения завершенного сертификата на большее количество компьютеров, чем там, где вы генерировали запрос сертификата, в зависимости от того, какой это HSM), но после установки сертификата на машине он выглядит как обычный сертификат с закрытым ключом, и вы просто используете его, как любой другой сертификат.

...