我有一個Windows證書頒發機構,用於通過.net/c#發佈客戶端身份驗證證書。我已經能夠成功地通過通過COM調用證書頒發機構的API來以編程方式發佈證書。我在創建客戶端時頒發新證書。如何驗證證書是由特定證書頒發機構創建的?
在運行時,這些客戶端將證書附加到請求到我的服務器。如何以編程方式驗證X509Certificate2是否由我的證書頒發機構的根證書籤名(並拒絕由任何其他源簽名的證書)?
我有一個Windows證書頒發機構,用於通過.net/c#發佈客戶端身份驗證證書。我已經能夠成功地通過通過COM調用證書頒發機構的API來以編程方式發佈證書。我在創建客戶端時頒發新證書。如何驗證證書是由特定證書頒發機構創建的?
在運行時,這些客戶端將證書附加到請求到我的服務器。如何以編程方式驗證X509Certificate2是否由我的證書頒發機構的根證書籤名(並拒絕由任何其他源簽名的證書)?
我這樣做了很多。這裏有一些簡單的代碼可以使用。
if (!isChainValid)
塊中的部分是產生一個相當錯誤的消息。如果你不想要,你不必使用它,但如果鏈不能建立,你應該拋出一個錯誤。鏈元素是檢查你的根的必要條件。
X509Certificate2 authority = GetAuthorityCertificate();
X509Certificate2 certificateToValidate = GetCertificateToValidate();
X509Chain chain = new X509Chain();
chain.ChainPolicy.RevocationMode = X509RevocationMode.NoCheck;
chain.ChainPolicy.RevocationFlag = X509RevocationFlag.ExcludeRoot;
chain.ChainPolicy.VerificationFlags = X509VerificationFlags.AllowUnknownCertificateAuthority;
chain.ChainPolicy.VerificationTime = DateTime.Now;
chain.ChainPolicy.UrlRetrievalTimeout = new TimeSpan(0, 0, 0);
// This part is very important. You're adding your known root here.
// It doesn't have to be in the computer store at all. Neither certificates do.
chain.ChainPolicy.ExtraStore.Add(authority);
bool isChainValid = chain.Build(certificateToValidate);
if (!isChainValid)
{
string[] errors = chain.ChainStatus
.Select(x => String.Format("{0} ({1})", x.StatusInformation.Trim(), x.Status))
.ToArray();
string certificateErrorsString = "Unknown errors.";
if (errors != null && errors.Length > 0)
{
certificateErrorsString = String.Join(", ", errors);
}
throw new Exception("Trust chain did not complete to the known authority anchor. Errors: " + certificateErrorsString);
}
// This piece makes sure it actually matches your known root
var valid = chain.ChainElements
.Cast<X509ChainElement>()
.Any(x => x.Certificate.Thumbprint == authority.Thumbprint);
if (!valid)
{
throw new Exception("Trust chain did not complete to the known authority anchor. Thumbprints did not match.");
}
錯誤將永遠不會爲空;) – HelloWorld
@HelloWorld好吧,如果我今天寫這篇文章的話,我只會使用'if(errors?.Length> 0)'。 :) C#6.很高興知道;我沒有深入研究ToArray()實現,看看如果Select()的IEnumerable沒有返回結果會發生什麼。 –
@ChrisBenard檢查證書是否與您已知的根目錄相匹配的代碼確實沒問題?這段代碼應該匹配做這樣的事情,幾乎總是返回true:'chain.ChainElements.Cast
如果你說你有一個根(這是自簽名)證書,那麼你唯一的選擇是保持你的服務器上可用的根證書(當然沒有私鑰),並執行證書驗證程序你的根證書。這是驗證服務器證書鏈的Web客戶端的鏡像情況。
我完全是這種情況。我會澄清我的問題,但我正在尋找驗證c#中籤名所需的特定代碼。 –
@Jeffrey我知道這是如何在我們的SecureBlackbox for .NET中完成的,但不知道如何完成純.NET Framework。 –
可能有更好的方法,但請查看[X509Chain](http://msdn.microsoft.com/zh-cn/library/system.security.cryptography.x509certificates.x509chain.aspx)類。文檔示例顯示的代碼沿着鏈條逐步檢查每個元素。 –
您還可以使用內置的方法Verify()
爲X509Certificate2
。
X509Certificate2 certificateToValidate = GetCertificateToValidate();
bool valid = certificateToValidate.Verify()
應該是security.se(也許) – Woot4Moo
爲什麼呢?我的問題是如何驗證登錄代碼... –
你有沒有找到一種方法來編碼? – MiguelM