Вам необходимо использовать функцию 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
пространство имен.
Затем подготовьте коллекцию использования ключей:
- создайте новый экземпляр класса
OidCollection
. - добавить требуемые OID в коллекцию.
- Использовать созданную коллекцию OID для создания экземпляра класса
X509EnhancedKeyUsageExtension
.Это допустимая перегрузка ctor: X509EnhancedKeyUsageExtension(OidCollection, Boolean)
. RawData
свойство расширения EKU будет содержать байтовый массив в кодировке ASN.1, который будет передан в функцию CertSetCertificateContextProperty
.
Последний параметр функции CertSetCertificateContextProperty
имеет тип IntPtr
и ожидает указатель на неуправляемый блок памяти, поэтому:
- Используйте
Marshal.AllocHGlobal(eku.RawData.Length)
для выделения буфера правильного размера в неуправляемой памяти. - Используйте перегрузку статического метода
Marshal.Copy(byte[], IntPtr, int, int)
для копирования массива байтов eku.RawData
в неуправляемый указатель, полученный на шаге 1. - вызывает функцию
CertSetCertificateContextProperty
.Если он возвращает true
, то все в порядке.
После завершения всей работы вы должны освободить неуправляемые ресурсы, чтобы избежать утечки памяти.Используйте метод Marshal.FreeHGlobal(IntPtr)
, чтобы освободить указатель, полученный во время вызова Marshal.AllocHGlobal
.