2016-04-04 29 views
1

kullanarak bir inf dosyasından CSR Oluşturma:altında bir "Certreq.exe -yeni -q request.inf request.csr" ile CSR üretmek üzere ben bir INF dosyası kullanıyorum .NET

[Version] 
Signature= "$Windows NT$" 

[NewRequest] 
Subject = "CN=subject" 
KeyLength = 2048 
Exportable = TRUE 
MachineKeySet = TRUE 
SMIME = FALSE 
PrivateKeyArchive = FALSE 
UserProtected = FALSE 
UseExistingKeySet = FALSE 
ProviderName = "Microsoft RSA SChannel Cryptographic Provider" 
ProviderType = 12 
RequestType = CMC 
KeyUsage = 0xa0 
KeyAlgorithm = RSA 
HashAlgorithm = sha256 

[EnhancedKeyUsageExtension] 
OID=1.3.6.1.5.5.7.3.1 

Bunu, .NET sınıfları aracılığıyla ve tercihen CSR'yi oluşturulduktan sonra bir dosyaya vermek zorunda kalmadan yapabileceğim bir yol var mı?

Yardımlarınız için çok teşekkürler.

+0

Yapabileceğiniz en yakın şey, ['CertEnroll'] için bir COM referansı eklemektir (https://msdn.microsoft.com/en-us/library/windows/desktop/aa374863 (v = vs.85)) .aspx) ancak bir INF dosyasını işlemek için bir yol görmüyorum (Win32 API'leri de var). INF dosyası, 'certreq' özel bir şey gibi görünüyor. INF dosyasını veya sadece INF/certreq'in ne yaptığını yapabilecek bir .NET API'sini kullanmak zorunda mısınız? – vcsjones

+0

Merhaba @vcsjones, INF dosyasının yaptığı şeyi yapabilen bir .NET API'si iyi olurdu. Herhangi bir öneriniz/örneğiniz var mı? Yardım için teşekkürler. –

cevap

0

Bunu yapmanın bir yolu CertEnroll. CertEnroll, yukarıdaki örneğiniz gibi bir INF dosyasını işleyemez. Bu, certreq'e özgüdür (yine de sizi INF'yi ayrıştırmaktan başka bir şey kalmaz).

CertEnroll bir COM kitaplığıdır, ancak yine de .NET'te kullanılabilecek kadar kolaydır. İlk önce, ona bir referans ekleyin. COM referansı eklemek biraz farklı. Ancak, CertEnroll'un Windows XP veya Windows Vista'da mevcut olmadığını unutmayın. İlk önce projenizde "Referanslar" ı sağ tıklayın ve Referans Ekle'yi seçin. "COM" menüsü altında "CertEnroll 1.0 Tip Kitaplığı" nı seçin.

İşlevselliğin eti CX509CertificateRequestCmc arabirimidir. C# COM arabirimleri onları, bu nedenle bu tamamen geçerli "yeni" dir olabilir, biraz özeldir:

var req = new CX509CertificateRequestCmc(); 

Yani, CertEnroll için INF çevirmek için, ben buna benzer bir şey olmazdı düşünüyorum:

var req = new CX509CertificateRequestPkcs10(); 
req.Initialize(X509CertificateEnrollmentContext.ContextUser); 

//Set basic constraints 
var basicConstraints = new CX509ExtensionBasicConstraints(); 
basicConstraints.InitializeEncode(false, 0); 
req.X509Extensions.Add((CX509Extension)basicConstraints); 

//Set the hash algorithm 
var hashAlgorithm = new CObjectId(); 
hashAlgorithm.InitializeFromAlgorithmName(ObjectIdGroupId.XCN_CRYPT_HASH_ALG_OID_GROUP_ID, 0, 0, "sha256"); 
req.HashAlgorithm = hashAlgorithm; 

//Set the enhanced key usage 
var eku = new CX509ExtensionEnhancedKeyUsage(); 
var serverAuth = new CObjectId(); 
serverAuth.InitializeFromValue("1.3.6.1.5.5.7.3.1"); 
var oids = new CObjectIds(); 
oids.Add(serverAuth); 
eku.InitializeEncode(oids); 
eku.Critical = false; 

var privateKey = req.PrivateKey; 
//Allow export as the INF does 
privateKey.ExportPolicy = X509PrivateKeyExportFlags.XCN_NCRYPT_ALLOW_EXPORT_FLAG; 
privateKey.Length = 2048; 

//Set the algorithm explicitly 
var rsa = new CObjectId(); 
rsa.InitializeFromAlgorithmName(ObjectIdGroupId.XCN_CRYPT_ANY_GROUP_ID, 0, 0, "RSA"); 
privateKey.Algorithm = rsa; 

privateKey.ProviderName = "Microsoft RSA SChannel Cryptographic Provider"; 
privateKey.ProviderType = X509ProviderType.XCN_PROV_RSA_SCHANNEL; //12 
privateKey.KeyUsage = (X509PrivateKeyUsageFlags)0xA0; 
privateKey.Existing = false; 
privateKey.KeyProtection = X509PrivateKeyProtection.XCN_NCRYPT_UI_NO_PROTECTION_FLAG; 
privateKey.MachineContext = true; 

var dn = new CX500DistinguishedName(); 
dn.Encode("CN=subject", X500NameFlags.XCN_CERT_NAME_STR_NONE); 
req.Subject = dn; 

var cmc = new CX509CertificateRequestCmc(); 
cmc.InitializeFromInnerRequest(req); 
cmc.ArchivePrivateKey = false; 
cmc.Encode(); 
var data = cmc.RawData[EncodingType.XCN_CRYPT_STRING_BASE64REQUESTHEADER]; 
Console.WriteLine(data); 

Sonunda "data" değişkeni, tümü diske kaydetmeden, isteği içerir.

Burada bir şeylerin eksik olması muhtemeldir, ancak bir sertifika isteği oluşturuyor. Yapılması gereken başka düzeltmeler için CertEnroll documentation'a danışırdım.