由于
Windows Azure中存在错误,因此必须将Windows 8应用程序中与Azure REST API一起使用的所有自签名客户端证书指定为扩展验证证书.
为了提供更好的用户体验,我尝试在远程服务器上生成此自签名证书.我正在使用Certificate Enrolment API,一个作为Windows的一部分分发的COM库,如this answer到问题How to create a self-signed certificate using C#?中所述
public static X509Certificate2 CreateSelfSignedCertificate( string cname,string friendlyName,string password) { // create DN for subject and issuer var dn = new CX500distinguishedname(); dn.Encode("CN=" + cname,X500NameFlags.XCN_CERT_NAME_STR_NONE); // create a new private key for the certificate CX509PrivateKey privateKey = new CX509PrivateKey(); privateKey.ProviderName = "Microsoft Base Cryptographic Provider v1.0"; privateKey.MachineContext = true; privateKey.Length = 2048; privateKey.KeySpec = X509KeySpec.XCN_AT_SIGNATURE; // use is not limited privateKey.ExportPolicy = X509PrivateKeyExportFlags.XCN_NCRYPT_ALLOW_PLAINTEXT_EXPORT_FLAG; privateKey.Create(); // Use the stronger SHA512 hashing algorithm var hashobj = new CObjectId(); hashobj.InitializefromAlgorithmName( ObjectIdGroupId.XCN_CRYPT_HASH_ALG_OID_GROUP_ID,ObjectIdPublicKeyFlags.XCN_CRYPT_OID_INFO_PUBKEY_ANY,AlgorithmFlags.AlgorithmFlagsNone,"SHA512"); // Create the self signing request var cert = new CX509CertificateRequestCertificate(); cert.InitializefromPrivateKey( X509CertificateEnrollmentContext.ContextMachine,privateKey,string.Empty); cert.Subject = dn; cert.Issuer = dn; // the issuer and the subject are the same cert.NotBefore = DateTime.Now; cert.NotAfter = DateTime.Now.AddYears(50); cert.HashAlgorithm = hashobj; var clientAuthenticationOid = new CObjectId(); clientAuthenticationOid.InitializefromValue("1.3.6.1.5.5.7.3.2"); // Set up cert to be used for Client Authentication. var oids = new CObjectIds(); oids.Add(clientAuthenticationOid); var eku = new CX509ExtensionEnhancedKeyUsage(); eku.InitializeEncode(oids); cert.X509Extensions.Add((CX509Extension)eku); // Add the certificate policy. var policy = new CCertificatePolicy(); policy.Initialize(clientAuthenticationOid); // THIS IS WRONG - NEEDS A DIFFERENT QUALIFIER var qualifier = new CPolicyQualifier(); qualifier.InitializeEncode( "c0",PolicyQualifierType.PolicyQualifierTypeUserNotice); policy.PolicyQualifiers.Add(qualifier); var policies = new CCertificatePolicies(); policies.Add(policy); var ecp = new CX509ExtensionCertificatePolicies(); ecp.InitializeEncode(policies); cert.X509Extensions.Add((CX509Extension)ecp); cert.Encode(); // Do the final enrolment process var enroll = new CX509Enrollment(); enroll.Initializefromrequest(cert); // load the certificate enroll.CertificateFriendlyName = friendlyName; string csr = enroll.CreateRequest(); // Output the request in base64 // and install it back as the response enroll.installresponse( installresponseRestrictionFlags.AllowUntrustedCertificate,csr,EncodingType.XCN_CRYPT_STRING_BASE64,""); // no password // output a base64 encoded PKCS#12 for import to .NET var base64encoded = enroll.CreatePFX( password,PFXExportOptions.PFXExportChainWithRoot); // instantiate the target class with the PKCS#12 data return new X509Certificate2( System.Convert.FromBase64String(base64encoded),password,X509KeyStorageFlags.Exportable); }
我发现ICertificatePolicy
界面似乎代表了正确的结构类型,但我无法推断出正确使用的IPolicyQualifier
.在我的代码中,限定符是
为清楚起见,您可以在此处配置Windows 8证书管理器中的信息:
关闭,但还没有.
是否有另一种方法将数据加载到IPolicyQualifier中,以便它可能使用InitialiseDecode方法产生预期的结果?
解决方法
如果要将客户端身份验证OID设置为“1.3.6.1.5.5.7.2”,那么我认为您的代码确实可以正常工作.如何验证代码没有设置此值?
X509Certificate2 xx = CreateSelfSignedCertificate("Avkash CNAME","Test User Friendly Name","xx"); byte[] bCertExported = xx.Export(X509ContentType.Pkcs12,"xx"); File.WriteallBytes("c:\\InstallBox\\test.pfx",bCertExported);
我在本地安装证书并检查它是否为客户端身份验证OID后,它显示如下:
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。