撤销X509证书

时间:2012-01-30 20:08:41

标签: c# .net security pki x509certificate2

如何在撤销X509Certificate时以编程方式获取?如果证书被撤销,我可以获取信息,但我需要在撤销时获取,我认为CRL列表有该信息,但有人可以告诉我如何阅读。

8 个答案:

答案 0 :(得分:2)

通过以下方式检查撤销状态:(a)获取CRL列表并检查证书是否列在那里,以及(b)向服务器发送OCSP请求以检查它。

.NET不允许你这样做。 CryptoAPI可能有一些用于这些操作的方法,但最简单的方法是使用.NET的第三方库。 BouncyCastle声称对OCSP和CRL有一些支持,我们的SecureBlackbox为OCSP和CRL提供了完整的支持(客户端和服务器组件都可用),我们还提供了一个执行完整证书验证的组件(所有CRL和OCSP检查和通过一次方法调用,在需要时进行HTTP和LDAP通信)。

答案 1 :(得分:1)

使用x509.h文件中的此API使用openssl 1.0 /或以上版本

X509_CRL_get0_by_cert(X509_CRL * crl,X509_REVOKED ** ret,X509 * x);

证书中的X要检查;
Ret是撤销结构的地址,其中撤销的原因和所有存储的 crl是CRL。

答案 2 :(得分:1)

为未来的读者。

正如已经说过的那样,.NET目前不公开公共类,也不公开X.509证书撤销列表,也不公开OCSP消息传递。当然,您可以编写自己的代码或使用第三方库。

您可以从PowerShell PKI模块项目(PKI.Core.dll库)尝试我自己的CryptoAPI托管扩展。支持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;
    }
}

答案 3 :(得分:1)

CRL作为OID存储在X509Certificate对象的extensions属性中。 OID FriendlyName和Value是' 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];
    }
}

答案 4 :(得分:1)

我没有资格支持上面@Hive 的回答,但这正是我所需要的,除了语言。我在下面发布了我的 PowerShell 端口:

$cert = (Get-ChildItem -Path Cert:\LocalMachine\My | Where-Object {$_.Subject -match "SUBJECT NAME*"})

function IndexOfByte([byte[]]$instance, [byte]$item, [int]$start)
{
    $len = $instance.Length
    for ($i = $start; $i -lt $len; $i++) {
        if ($instance[$i] -eq $item) { return $i }
    }

    return -1;
}

$crls = $cert.Extensions | ? { $_.Oid.FriendlyName -eq "CRL Distribution Points" }

$prev = -2;
[System.Collections.ArrayList]$items = @();

while ($prev -ne -1 -and $crls.RawData.Length -gt $prev + 1)
{
    if($prev -eq -2) { $y = 8 } else {$y = $prev + 1}
    $next = IndexOfByte -instance $crls.RawData -item 0x86 -start $y
    if ($next -eq -1) {
        if ($prev -ge 0) {
            $item = [system.Text.Encoding]::UTF8.GetString($crls.RawData, $prev + 2, $crls.RawData.Length - ($prev + 2));
            $items.Add($item);
        }
        break;
    }

    if ($prev -ge 0 -and $next -gt $prev) {
        $item = [system.Text.Encoding]::UTF8.GetString($crls.RawData, $prev + 2, $next - ($prev + 2));
        $items.Add($item);
    }
    $prev = $next;
}

Write-Host "Certificate CRLs: `n$($items | out-string)"

答案 5 :(得分:0)

答案 6 :(得分:0)

第一步是从证书中提取CRL分发点,然后将证书的序列号与分发点中CRL的内容进行匹配。

这是提取具有更少幻数和比特颤动的CRL分布点的另一种方法。 (在.NET Core 2.1中测试)

var path = "<path to signed file>";
// get certificate
var cert = new X509Certificate2(path);
// extract the CRL distribution points information
var crlInfo = cert.Extensions["2.5.29.31"];
var crlDistribitionPoints = new AsnEncodedData(crlInfo.Oid, crlInfo.RawData).Format(false);
Console.Writeline(crlDistribitionPoints);    

答案 7 :(得分:-1)

当你说被撤销时,你的意思是无效的吗?如果它被撤销我不希望它在您的代码中到达请求,因为Web服务器将首先阻塞。

如果您使用x509certificate2,它是从x509certificate派生的,那么您可以检查更多属性;下面的链接有很多例子。

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