有一个GlobalSignCA。在大多数情况下,其根证书已存在于Windows证书存储中。 但是有时(尤其是在旧的Windows版本上),存储中不包含证书。
我需要检查证书是否存在,如果不存在则将其导入。我将证书导出到文件中,并使用以下代码将其导入:
joda.time
代码添加了证书,但检查了所有证书用途:
我不想为证书添加额外的用途,只想设置具有其他根CA的证书,如下所示:
如何以编程方式进行?
答案 0 :(得分:0)
您需要使用CertSetCertificateContextProperty
函数来设置存储附加属性。
在dwPropId
参数中,您传递CERT_ENHKEY_USAGE_PROP_ID
。您可以在Wincrypt.h C ++头文件中找到其数值。在给定的情况下,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
类的新实例。X509EnhancedKeyUsageExtension
类。此ctor重载很好:X509EnhancedKeyUsageExtension(OidCollection, Boolean)
。RawData
属性将包含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
调用期间获取的指针。