2016-04-04 18 views
1

Ich bin eine INF-Datei wie die unten einen CSR mit „certreq.exe -neue -q request.inf request.csr“ zu generieren:Generieren eines CSR aus einer INF-Datei .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 

Gibt es eine Möglichkeit, dass ich dies über .NET-Klassen tun kann, und vorzugsweise, ohne die CSR in eine Datei exportieren zu müssen, sobald sie generiert wurde?

Vielen Dank für Ihre Hilfe.

+0

Das nächste, was Sie tun können, ist eine COM-Referenz zu ['CertEnroll'] hinzufügen (https://msdn.microsoft.com/en-us/library/windows/desktop/aa374863 (v = vs.85) .aspx), aber ich sehe keinen Weg dafür, eine INF-Datei zu verarbeiten (es gibt auch Win32-APIs). Die INF-Datei scheint etwas zu sein, das für 'certreq' spezifisch ist. Müssen Sie unbedingt die INF-Datei oder nur eine .NET-API verwenden, die das tun kann, was das INF/certreq macht? – vcsjones

+0

Hallo @vcsjones, eine .NET-API, die tun kann, was die INF-Datei macht, wäre in Ordnung. Hast du irgendwelche Vorschläge/Beispiele? Danke für die Hilfe. –

Antwort

0

So eine Möglichkeit, die Sie tun können, ist mit CertEnroll. CertEnroll kann eine INF-Datei nicht wie Ihr Beispiel oben verarbeiten, das ist nur für certreq (obwohl es nichts gibt, was Sie davon abhält, das INF selbst zu analysieren).

CertEnroll ist eine COM-Bibliothek, aber immer noch einfach genug in .NET zu verwenden. Fügen Sie zuerst einen Verweis hinzu. Das Hinzufügen einer COM-Referenz ist etwas anders. Beachten Sie jedoch, dass CertEnroll nicht unter Windows XP oder Windows Vista verfügbar ist.

Klicken Sie zunächst in Ihrem Projekt mit der rechten Maustaste auf "Referenzen" und wählen Sie "Referenz hinzufügen". Wählen Sie im Menü "COM" "CertEnroll 1.0 Type Library".

Das Fleisch der Funktionalität ist die CX509CertificateRequestCmc Schnittstelle. COM-Schnittstellen in C# sind etwas Besonderes, Sie können „neue“ sie, so dass diese vollkommen gültig ist:

var req = new CX509CertificateRequestCmc(); 

Also, zu übersetzen Ihre INF zu CertEnroll, ich glaube, es ist etwas ähnlich wie diese aussehen würde:

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); 

Die Variable "data" am Ende enthält die Anfrage, alles ohne sie auf der Festplatte zu speichern.

Es ist ziemlich wahrscheinlich, dass etwas von hier fehlt, aber es erzeugt eine Zertifikatsanforderung. Ich würde die CertEnroll documentation für weitere Optimierungen konsultieren, die vorgenommen werden müssen.