Могу ли я создать CSR из Azure Key Vault?

Я хочу сгенерировать закрытый ключ в HSM в Azure Key Vault, а затем создать запрос на подпись сертификата, CSR, содержащий соответствующий открытый ключ.

Возможно ли сегодня создание открытого ключа, а затем и CSR в Key Vault - я не вижу упоминания о создании соответствующего открытого ключа в документации? (Или, может быть, я просто не понимаю природу HSM?)

Похоже, что резервным вариантом является создание ключей и CSR в другом месте и импорт закрытого ключа в Key Vault HSM. Это явно не так хорошо, как закрытый ключ, никогда не существовавший за пределами HSM.


person flensted    schedule 18.01.2016    source источник


Ответы (2)


Вот способ сделать это в Windows

  1. # P2 #
    // Assuming you have a keyVaultClient object using the SDK
    var keyBundle = keyVaultClient.CreateKeyAsync(keyVaultUri, "myKey01", "RSA-HSM", 2048).GetAwaiter().GetResult();
    
  2. # P3 #
    var rsaCryptoProvider = new RSACryptoServiceProvider();
    var rsaParameters = new RSAParameters()
    {
        Modulus = keyBundle.Key.N,
        Exponent = keyBundle.Key.E
    };
    rsaCryptoProvider.ImportParameters(rsaParameters);
    var cspBlob = rsaCryptoProvider.ExportCspBlob(false);
    
  3. # P4 # # P5 #
    # P6 #
    [DllImport("ncrypt.dll", CharSet = CharSet.Unicode), SuppressUnmanagedCodeSecurity]
    private static extern ErrorCode NCryptOpenStorageProvider(
        [Out] out SafeNCryptProviderHandle phProvider,
        string pszProviderName,
        uint dwFlags);
    
    # P7 #
    SafeNCryptProviderHandle providerHandle = null;
    var result = NCryptOpenStorageProvider(
        out providerHandle,
        null,
        0);
    
    # P8 #
    [DllImport("ncrypt.dll", CharSet = CharSet.Unicode), SuppressUnmanagedCodeSecurity]
    private static extern int NCryptImportKey(
        SafeNCryptProviderHandle hProvider,
        IntPtr hImportKey,     // NCRYPT_KEY_HANDLE
        string pszBlobType,
        IntPtr pParameterList, // NCryptBufferDesc *
        [Out] out SafeNCryptKeyHandle phKey,
        [MarshalAs(UnmanagedType.LPArray)] byte[] pbData,
        int cbData,
        uint dwFlags);
    
    # P9 #
    SafeNCryptKeyHandle keyHandle;
    var result = NCryptImportKey(
        providerHandle,
        IntPtr.Zero,
        "CAPIPUBLICBLOB",
        IntPtr.Zero,
        out keyHandle,
        cspBlob,
        cspBlob.Length,
        0x00000040);
    
    < / blockquote> # P10 #
  4. Заполните остальные поля PKCS10 (CSR) и ASN1 закодирует его.

  5. # P12 #
    # P13 #
  6. Присоедините подпись к закодированному результату (5), и ANS1 снова закодирует его.

person Rohit Manohar    schedule 25.01.2016
comment
Привет, Рохит, большое спасибо. Я постараюсь переварить это позже; Должен признать, что я не очень разбираюсь в Crypto API - предыдущем, текущем и следующем поколении. Но, по крайней мере, ваш ответ указывает на то, что выход есть. Для нас это действительно интересно при создании аутентификации на основе токенов, в которой все доверие зависит от защиты ключа подписи токена. - person flensted; 26.01.2016
comment
И разве не имеет смысла встроить поддержку генерации CSR прямо в Key Vault? Разве это не частый случай генерации закрытого ключа? - person flensted; 26.01.2016
comment
То же самое для меня. В Key Vault отсутствуют самые основные функции HSM, такие как внутренняя подпись CSR (без необходимости экспортировать драгоценный закрытый ключ). - person NOP-MOV; 21.06.2020

Возможно, вам будет проще использовать COM-интерфейсы Windows CertEnroll: создайте и инициализируйте объект IX509CertificateRequestPkcs10 (https://msdn.microsoft.com/en-us/library/windows/desktop/aa377505(v=vs.85).aspx), заполните его свойства, затем получите его свойство RawDataToBeSigned и отправьте его в Azure Key Vault для подписи. Это вызывается из собственного кода, .NET и т. Д.

Альтернативный [но более сложный] подход - использовать базовые API Windows, на которых построены COM-интерфейсы. Этот образец (https://msdn.microsoft.com/en-us/library/windows/desktop/aa382364(v=vs.85).aspx) проходит через создание и подписание такого PKCS # 10. Вне всяких сомнений, вы сможете адаптировать образец, заменив вызовы CryptSignAndEncodeCertificate на:

  1. Вызов CryptEncodeObjectEx для ASN.1 кодирует объект CERT_REQUEST_INFO в двоичный код; а также

  2. Вызов Key Vault для подписи этого двоичного большого двоичного объекта.

  3. Затем вам нужно будет создать CERT_SIGNED_CONTENT_INFO, установив:

    а. Член ToBeSigned для закодированного двоичного файла от # 1;

    б. Член SignatureAlgorithm алгоритма, используемого для подписи с помощью Key Vault; а также

    c. Член подписи для подписи, возвращенной из Key Vault.

  4. Затем вы должны снова вызвать CryptEncodeObjectEx, чтобы ASN.1 закодировал результирующий PKCS # 10 в двоичный код.

Вышеприведенное решение действительно, но на самом деле будет реализовано то, что IMO представляет собой более сложный подход через взаимодействие .NET (замена вызовов Crypto API v1.0 в примере вызовами Crypto Next Gen). Я бы не стал там начинать, если бы у меня не было особой причины.

person Tochi Ezebube    schedule 26.01.2016