已吊销X509证书
本文关键字:证书 X509 | 更新日期: 2023-09-27 18:21:51
当X509Certificate被吊销时,我如何通过编程获取?如果证书被吊销,我可以获得信息,但我需要获得吊销的时间,我认为CRL列表中有这些信息,但有人能告诉我如何阅读吗。
通过(a)获取CRL列表并检查证书是否在其中列出,以及(b)向服务器发送OCSP请求以进行检查来检查吊销状态。
.NET不允许您这样做。CryptoAPI可能有一些方法来执行这些操作,但最简单的是使用.NET的第三方库。BouncyCastle声称对OCSP和CRL有一些支持,我们的SecureBlacbox为OCSP和CRLs提供了完整的支持(客户端和服务器组件都可用),此外,我们还提供了一个组件,该组件通过一个方法调用来执行完整的证书验证(包括所有CRL和OCSP检查以及需要时的HTTP和LDAP通信)。
CRL作为OID存储在X509Certificate对象的extensions属性中。OID FriendlyName和Value分别为"CRL分发点"answers"2.5.29.31"。在证书扩展中搜索值为2.5.29.31的OID,然后可以解析原始数据并获取分发点。
我在这里找到了以下代码示例。我在公开签名证书和内部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];
}
}
使用x509.h文件中的此API使用openssl 1.0/或更高版本
X509CRL_get0_by_cert(X509CRL*CRL,X509_REVOKED**ret,X509*x);
您要检查的证书中的X
Ret是吊销结构的地址,其中存储了吊销原因和所有内容
crl是crl
面向未来的读者。
如前所述,.NET目前不公开公共类,也不公开X.509证书吊销列表,也不公布OCSP消息。当然,您可以编写自己的代码或使用第三方库。
您可以从PowerShell PKI模块项目(PKI.Core.dll库)中尝试我自己的CryptoAPI托管扩展。支持X509CRL托管类(建立在CryptoAPI本机函数之上):X509CRL2类。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;
}
}
我没有资格支持@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)"
这可以帮助您:
http://blogs.msdn.com/b/alejacma/archive/2010/05/10/how-to-get-info-from-client-certificates-issued-by-a-ca-c.aspx
谨致问候。
第一步是从证书中提取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);
当你说撤销时,你的意思是无效吗?如果它被撤销了,我不希望它会在你的代码中到达请求,因为网络服务器会首先阻止它。
如果您使用x509certificate2,它是从x509certification派生而来的,那么您可以检查更多的属性;下面的链接上有很多例子。
http://msdn.microsoft.com/en-us/library/system.security.cryptography.x509certificates.x509certificate2.aspx