Как установить цели сертификата? - PullRequest
0 голосов
/ 20 декабря 2018

Есть GlobalSign CA.В большинстве случаев его корневой сертификат уже существует в хранилище сертификатов Windows.Но иногда (особенно в старых версиях Windows) хранилище не содержит сертификат.

Мне нужно проверить, существует ли сертификат, и импортировать его, если его нет.Я экспортировал сертификат в файл и импортировал его, используя код ниже:

public void ImportCertificate(StoreName storeName,
    StoreLocation location,
    byte[] certificateData)
{
    X509Store x509Store = new X509Store(storeName, location);
    X509Certificate2 certificate = new X509Certificate2(certificateData);
    x509Store.Open(OpenFlags.ReadWrite);
    x509Store.Add(certificate);
    x509Store.Close();
}

Код добавляет сертификат, но проверяются все цели сертификата:

Result

Я не хочу добавлять в сертификат дополнительные цели, просто хочу установить те, у которых есть другие корневые CA, как показано ниже:

Expect

Как это сделать программно?

1 Ответ

0 голосов
/ 20 декабря 2018

Вам необходимо использовать функцию CertSetCertificateContextProperty для установки свойств магазина.

В параметре dwPropId вы передаете CERT_ENHKEY_USAGE_PROP_ID.Вы можете найти его числовое значение в заголовочном файле C ++ Wincrypt.h.В данном случае dwPropId равно 9:

#define CERT_ENHKEY_USAGE_PROP_ID           9

В dwFlags вы передаете ноль (0).

В параметре pvData (который равен IntPtrв управляемой подписи) вы передаете неуправляемый указатель в байтовый массив в кодировке ASN.1, представляющий коллекцию идентификаторов объектов, где каждый OID представляет явно разрешенное использование ключа.

Вот подпись взаимодействия:

[DllImport("Crypt32.dll", CharSet = CharSet.Auto, SetLastError = true)]
internal static extern Boolean CertSetCertificateContextProperty(
    [In] IntPtr pCertContext,
    [In] UInt32 dwPropId,
    [In] UInt32 dwFlags,
    [In] IntPtr pvData,
);

Добавьте ссылку на использование в System.Runtime.InteropServices пространство имен.

Затем подготовьте коллекцию использования ключей:

  1. создайте новый экземпляр класса OidCollection.
  2. добавить требуемые OID в коллекцию.
  3. Использовать созданную коллекцию OID для создания экземпляра класса X509EnhancedKeyUsageExtension.Это допустимая перегрузка ctor: X509EnhancedKeyUsageExtension(OidCollection, Boolean).
  4. RawData свойство расширения EKU будет содержать байтовый массив в кодировке ASN.1, который будет передан в функцию CertSetCertificateContextProperty.

Последний параметр функции CertSetCertificateContextProperty имеет тип IntPtr и ожидает указатель на неуправляемый блок памяти, поэтому:

  1. Используйте Marshal.AllocHGlobal(eku.RawData.Length) для выделения буфера правильного размера в неуправляемой памяти.
  2. Используйте перегрузку статического метода Marshal.Copy(byte[], IntPtr, int, int) для копирования массива байтов eku.RawData в неуправляемый указатель, полученный на шаге 1.
  3. вызывает функцию CertSetCertificateContextProperty.Если он возвращает true, то все в порядке.

После завершения всей работы вы должны освободить неуправляемые ресурсы, чтобы избежать утечки памяти.Используйте метод Marshal.FreeHGlobal(IntPtr), чтобы освободить указатель, полученный во время вызова Marshal.AllocHGlobal.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...