![](/img/trans.png)
[英]ASPX C# Control ID Naming - generate different Id with different Machines
[英]Generate and sign certificate in different machines C#
我需要生成用於代理之間安全通信的證書。 每個代理都會生成一個證書,並且必須將其發送到另一台機器上的系統 CA 進行簽名(並由其他代理信任)。 我正在使用 C# 和以下代理代碼執行此操作:
//generate certificate
ECDsa elipticCurveNistP256Key = ECDsa.Create(ECCurve.CreateFromValue("1.2.840.10045.3.1.7")); // nistP256 curve
CertificateRequest certificateRequest = new CertificateRequest("CN=" + agentId, elipticCurveNistP256Key, HashAlgorithmName.SHA256);
certificateRequest.CertificateExtensions.Add(
new X509BasicConstraintsExtension(false, false, 0, false));
certificateRequest.CertificateExtensions.Add(
new X509KeyUsageExtension(
X509KeyUsageFlags.DigitalSignature | X509KeyUsageFlags.NonRepudiation,
false));
// Add the SubjectAlternativeName extension
var sanBuilder = new SubjectAlternativeNameBuilder();
sanBuilder.AddIpAddress(IPAddress.Parse(agentIpAddress));
certificateRequest.CertificateExtensions.Add(sanBuilder.Build());
certificateRequest.CertificateExtensions.Add(
new X509EnhancedKeyUsageExtension(
new OidCollection
{
new Oid("1.3.6.1.5.5.7.3.8")
},
true));
certificateRequest.CertificateExtensions.Add(
new X509SubjectKeyIdentifierExtension(certificateRequest.PublicKey, false));
以及以下 CA 系統的代碼:
X509Certificate2 signedCertificate = certificateRequest.Create(
caCertificatePFX,
DateTimeOffset.UtcNow.AddDays(-1),
DateTimeOffset.UtcNow.AddDays(30),
new byte[] {1, 2, 3, 4});
當然,我也使用代碼在我這里沒有顯示的機器之間進行通信。 但我至少有兩個問題:
我希望將證書生成和簽名完全分開,但即使進行了大量嘗試,這也是我能夠開始工作的唯一代碼。 如果我沒記錯的話,這段代碼在 CA 系統上創建了證書,這不是理想的場景(CA 可以訪問代理私鑰),但如果我沒有找到更好的,我可以接受。
第二個問題是,即使我接受了第一個問題,我仍然需要將 CertificateRequest 對象從一台機器發送到另一台機器,並且 CertificateRequest 是不可序列化的。 我找到了 CreateSigningRequest() 方法,它“創建一個 ASN.1 DER 編碼的 PKCS#10 CertificationRequest 值,表示當前對象的狀態。” 但是我還沒有找到一種方法讓它再次成為 CertificateRequest 對象,以便我可以運行 CA 系統代碼。
有誰知道我怎么能做到這一點? 希望將證書生成和證書簽名完全分開,但如果不可能至少創建 CertificateRequest 對象。
我正在運行 .Net Framework 4.7.2,我需要維護它才能使用以前開發的 Windows 窗體。
謝謝
正如您所指出的,沒有辦法讀回 PKCS#10 請求。 這主要是因為缺少太多東西才能成為“OK”證書頒發機構,因此擁有閱讀器只會導致許多“壞”證書頒發機構。 (由於您的 CA 不支持吊銷,因此它也是一個“壞”CA,但您正在使用短期證書來緩解這種情況。)
PKCS#10 請求包含:
如果您不使用數據格式,則數據格式版本無關緊要,並且簽名對於“封閉”頒發者(僅向直接已知方頒發證書的 CA)來說並不重要。 因此,您只需要傳輸公鑰和請求所需的任何其他數據(查看您當前的代碼、代理 ID 和 IP 地址)。
唯一棘手的部分是發送公鑰……但是使用 .NET Core 3.0+,您可以將所有密鑰規范化為它們的 SubjectPublicKeyInfo 格式:
byte[] spki = elipticCurveNistP256Key.ExportSubjectPublicKeyInfo();
雖然PublicKey
類型擁有 ImportSubjectPublicKeyInfo 方法會非常聰明,但這還沒有發生。 對於通用解析,您想嘗試所有主要的密鑰類型,但由於您是另一側的封閉 CA,您可以先驗地知道它是 ECDSA:
using (ECDsa clientPub = ECDsa.Create())
{
clientPub.ImportSubjectPublicKeyInfo(transmittedSpki, out _);
// the rest of your code goes here.
}
我強烈建議使用 CA 軟件來簽署證書請求。 時期。
任何擁有 CA 代碼的嘗試都會使解決方案在許多方面變得不可靠、脆弱和容易出錯。 有多種選擇,從 Microsoft ADCS (Windows) 和 EJBCA (Windows/Linux) 開始。 任何其他設計都將是糟糕的。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.