2012-01-30 172 views
0

如何在X509Certificate被撤銷時以編程方式獲取?如果證書被撤銷,我可以獲得信息,但是我需要獲取何時被撤銷的信息,我認爲CRL列表具有該信息,但是有人可以告訴我如何閱讀該信息。已撤銷X509證書

回答

-1

當你說撤銷時,你的意思是無效嗎?如果它被撤銷,我不會期望它會在你的代碼中得到請求,因爲Web服務器將首先採取行動。

如果使用x509certificate2,這是從X509證書導出,那麼你有更多的屬性,您可以檢查;下面的鏈接中有很多例子。

http://msdn.microsoft.com/en-us/library/system.security.cryptography.x509certificates.x509certificate2.aspx

+0

是的,我認爲X509Certificate2,證書不是來自web請求,它來自證書文件。 – buda 2012-01-31 09:46:35

2

撤銷狀態由(a)獲得CRL列表,並且如果證書被列在那裏檢查,和(b)發送一個OCSP請求到服務器以檢查相同的檢查。

.NET不會讓你這樣做。 CryptoAPI可能有這些操作的一些手段,但最簡單的是使用.NET的第三方庫。 BouncyCastle聲稱對OCSP和CRL有一定的支持,而我們的SecureBlackbox爲OCSP和CRL提供完整的支持(客戶端和服務器組件都可用),同時我們還提供了一個執行完整證書驗證的組件(包括所有CRL和OCSP檢查以及通過一個方法調用,可以在需要時進行HTTP和LDAP通信)。

+0

你確定.NET不執行恢復檢查嗎? - 當一個解決方案無法在測試環境中從測試證書服務器訪問CRL時,我遇到了一些問題,但在很多年前,我不能保證它不是注入解決方案的安全組件。 – faester 2012-01-31 06:13:58

+0

對不起:看來IIS正在檢查證書恢復,這可能是我記得的。 – faester 2012-01-31 06:15:11

+0

@faester CrtypoAPI內部執行CRL和OCSP檢查,但它們不易於從.NET使用和控制。 – 2012-01-31 06:47:08

1

使用從x509.h文件使用OpenSSL這個API 1.0 /或以上版本

X509_CRL_get0_by_cert(X509_CRL * CRL,X509_REVOKED ** RET,X509 * X);

X在你想檢查的證書中;
Ret是撤銷結構的地址,其中撤銷的原因和所有存儲的
crl是CRL。

1

對於未來的讀者。如前所述,.NET目前不公開類,X.509證書撤銷列表以及OCSP消息傳遞都不公開。當然,您可以編寫自己的代碼或使用第三方庫。

你可以試試我自己的CryptoAPI託管擴展從PowerShell PKI模塊項目(PKI.Core.dll庫)。支持X509 CRL託管類(構建於CryptoAPI本機函數之上):X509CRL2 class。 RevokedCertificates屬性存儲撤銷證書的數組。另外,庫包含存儲在PKI.OCSP命名空間中的OCSP消息類(完全託管)。如果您的證書在AIA擴展中包含OCSP鏈接,則可以通過實例化OCSPRequest對象並調用OCSPRequest.SendRequest方法輕鬆地從X509Certificate2對象構造OCSP請求。返回對象是OCSPResponse類的一個實例。

基本上,竟被代碼看起來像這樣:

using System; 
using System.Security.Cryptography.X509Certificates; 
using PKI.OCSP; 

public class Class1 { 
    public static DateTime? GetrevocationDate(X509Certificate2 cert) { 
     OCSPRequest request = new OCSPRequest(cert); 
     OCSPResponse response = request.SendRequest(); 
     if (response.Responses[0].CertStatus == CertificateStatus.Revoked) { 
      return response.Responses[0].RevocationInfo.RevocationDate; 
     } 
     return null; 
    } 
} 

NULL將意味着該證書沒有被撤銷。

與X509 CRL代碼將如下這樣:

using System; 
using System.Security.Cryptography.X509Certificates; 

public class Class1 { 
    // crlRawData could a type of System.String and pass the path to a CRL file there. 
    public static DateTime? GetrevocationDate(X509Certificate2 cert, Byte[] crlRawData) { 
     X509CRL2 crl = new X509CRL2(crlRawData); 
     X509CRLEntry entry = crl.RevokedCertificates[cert.SerialNumber]; 
     if (entry != null) { 
      return entry.RevocationDate; 
     } 
     return null; 
    } 
} 
+0

中所述您使用X509CRL2的方法像冠軍一樣工作。謝謝!! – JonK 2015-01-22 16:40:48

0

的CRL被存儲爲在X509Certificate對象的擴展屬性的OID。 OID友好名稱和值是「CRL分發點」和「2.5.29.31」。在證書的擴展中搜索值爲2.5.29.31的OID,然後可以解析原始數據並獲取分發點。我發現下面的代碼示例here。我在公開簽署證書和內部Microsoft CA證書上進行了測試;它會返回URL或LDAP連接字符串。

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 

namespace System.Security.Cryptography.X509Certificates 
{ 
    public static class X509Certificate2Extensions 
    { 
     /// <summary> 
     /// Returns an array of CRL distribution points for X509Certificate2 object. 
     /// </summary> 
     /// <param name="certificate">X509Certificate2 object.</param> 
     /// <returns>Array of CRL distribution points.</returns> 
     public static string[] GetCrlDistributionPoints(this X509Certificate2 certificate) 
     { 
      X509Extension ext = certificate.Extensions.Cast<X509Extension>().FirstOrDefault(
       e => e.Oid.Value == "2.5.29.31"); 

      if (ext == null || ext.RawData == null || ext.RawData.Length < 11) 
       return EmptyStrings; 

      int prev = -2; 
      List<string> items = new List<string>(); 
      while (prev != -1 && ext.RawData.Length > prev + 1) 
      { 
       int next = IndexOf(ext.RawData, 0x86, prev == -2 ? 8 : prev + 1); 
       if (next == -1) 
       { 
        if (prev >= 0) 
        { 
         string item = Encoding.UTF8.GetString(ext.RawData, prev + 2, ext.RawData.Length - (prev + 2)); 
         items.Add(item); 
        } 

        break; 
       } 

       if (prev >= 0 && next > prev) 
       { 
        string item = Encoding.UTF8.GetString(ext.RawData, prev + 2, next - (prev + 2)); 
        items.Add(item); 
       } 

       prev = next; 
      } 

      return items.ToArray(); 
     } 

     static int IndexOf(byte[] instance, byte item, int start) 
     { 
      for (int i = start, l = instance.Length; i < l; i++) 
       if (instance[i] == item) 
        return i; 

      return -1; 
     } 

     static string[] EmptyStrings = new string[0]; 
    } 
}