[英]Digitally sign using root CA from certificate file in .NET
我必須使用證書和私鑰在C#中對某些數據進行數字簽名。 我使用的證書具有自定義的根CA和自定義的中間CA。
如果將根CA和中間CA安裝到Windows證書存儲區中, 則可以使用這樣的代碼進行簽名而不會出現任何問題:
var content = new ContentInfo(manifest);
var cms = new SignedCms(content, true);
var signer = new CmsSigner(SubjectIdentifierType.SubjectKeyIdentifier, myCertificate);
signer.SignedAttributes.Add(new Pkcs9SigningTime(DateTime.Now));
cms.ComputeSignature(signer);
return cms.Encode();
不幸的是,但是,我無法將根CA和中間CA安裝到服務器的證書存儲中(我正在使用Azure Web Apps)。 我正在嘗試找到一種方法,通過使用根CA證書和中間CA證書(如果它們存儲在磁盤上)來進行簽名。 我以為我可以在調用cms.Encode()
之前做類似的事情:
// add CAs from disk
var intermediateCACertificate = new X509Certificate2(@"pathToIntermediateCertificate.cer");
signer.Certificates.Add(intermediateCACertificate);
var rootCACertificate = new X509Certificate2(@"pathToRootCertificate.cer");
signer.Certificates.Add(rootCACertificate);
但是,當我執行此操作時,會引發CryptographicException "A certificate chain could not be built to a trusted root authority."
。
是否可以在不將非標准CA安裝到Windows證書存儲區的情況下進行數字簽名?
有可能的。
基本上,從SignedCms
類返回的BLOB可以包含除簽名本身之外的任意數量的任意證書。 通常這樣做是為了至少包括與消息進行簽名的證書,並可能包括任何其他中間證書,以便接收實體可以驗證簽名,直到它信任的根證書為止。
在調用上面的signer.Certificates.Add()
調用時,您正在添加要在輸出簽名BLOB中編碼的證書。 但是,將證書添加到此集合並不能暗示對它們的任何形式的“信任”。
您遇到的問題是這樣的事實:默認情況下,.NET SignedCms
類嘗試通過自動包含典型情況下將包含的證書來幫助您。 默認情況下,它包括鏈中除根以外的所有證書。 它通過嘗試使用在服務器的證書存儲中找到的證書構建證書鏈來實現此目的,如您所注意到的,當未安裝根/中間CA的證書時,證書鏈將失敗。
證書鏈的構建由CmsSigner.IncludeOption
屬性控制。 缺省值為X509IncludeOption.ExcludeRoot
。 此值和X509IncludeOption.WholeChain
都將在您的系統上失敗,因為該類將無法基於證書存儲中的內容構建鏈。
您可能想要做的如下:
signer.IncludeOption = X509IncludeOption.EndCertOnly;
signer.Certificates.Add(intermediateCACertificate);
signer.Certificates.Add(rootCACertificate);
這將包括您用來簽名的證書(當您指定EndCertOnly
時將包括該證書)以及顯式添加的中間證書和根證書。 SignedCms
不會嘗試構建證書鏈,因為它只需要包括已經提供的證書,因此不會引發任何異常。
順便說一句,您可能會得到與上述相同的結果:
signer.IncludeOption = X509IncludeOption.None;
signer.Certificates.Add(myCertificate);
signer.Certificates.Add(intermediateCACertificate);
signer.Certificates.Add(rootCACertificate);
在這種情況下,不會自動包括簽名證書,但是下一行將其顯式添加到集合中。
根據您的接收者信任的CA,有可能您不需要像上面那樣在鏈中包含所有證書,並且可能僅包含簽名證書就可以逃脫。 但是,我建議手動至少包括但不包括根目錄,因為這是.NET的默認行為。 確實,包括整個鏈條也沒有真正的危害,但是對於所有意圖和目的,接收者應該已經信任根CA,否則PKI的整個概念就會崩潰。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.