C# 如何在单平台和多平台上使用X509Certificate2正确验证SSL证书
我必须在一个非浏览器应用程序中验证几个SSL证书,用于应在IOS、Android和Linux上运行的C# 如何在单平台和多平台上使用X509Certificate2正确验证SSL证书,c#,mono,ssl-certificate,x509certificate2,C#,Mono,Ssl Certificate,X509certificate2,我必须在一个非浏览器应用程序中验证几个SSL证书,用于应在IOS、Android和Linux上运行的HttpRequests和websocket连接。 当通过HTTPS进行连接时,我会收到一个X509Certificate2对象数组,其中最下面的是服务器证书,最上面的是根CA(希望如此)。例如,当我连接到https://google.com我收到3份X509Certificate2,其中包含以下主题名称。名称: 0:“CN=google.com,O=google Inc,L=Mountain
HttpRequests
和websocket
连接。
当通过HTTPS
进行连接时,我会收到一个X509Certificate2
对象数组,其中最下面的是服务器证书,最上面的是根CA(希望如此)。例如,当我连接到https://google.com
我收到3份X509Certificate2
,其中包含以下主题名称。名称
:
- 0:
“CN=google.com,O=google Inc,L=Mountain View,S=California,C=US”
- 1:
“CN=Google互联网管理局G2,O=Google Inc,C=US”
- 2:
“CN=GeoTrust Global CA,O=GeoTrust Inc.,C=US”
- 信任链验证
- 主机名验证
- 证书撤销验证
X509Certificate2.Verify()
方法时,每次它都返回false
。我也不明白为什么它可以返回任何其他内容,然后false
,因为验证是独立进行的。相反,根据我对理论的理解,应该检查完整的链,即所有证书
然后我使用了X509Chain
类:
foreach (X509Certificate2 cert in allthreecerts)
{
X509Chain chain = new X509Chain();
X509ChainPolicy chainPolicy = new X509ChainPolicy()
{
RevocationMode = X509RevocationMode.Offline,
RevocationFlag = X509RevocationFlag.EntireChain
};
chain.ChainPolicy = chainPolicy;
if (!chain.Build(cert))
{
foreach (X509ChainElement chainElement in chain.ChainElements)
{
foreach (X509ChainStatus chainStatus in chainElement.ChainElementStatus)
{
Debug.WriteLine(chainStatus.StatusInformation);
}
}
}
}
这将为每个证书打印出RevocationStatusUnknown
和OfflineRevocation
同样,我不明白为什么这应该起作用,因为构建了一个链,每个证书都是独立的。父证书不应该是子证书的颁发,而应该是根CA吗
我认为我需要的东西,但不知道如何使用。
为了验证证书吊销,所有客户端都需要提供证书吊销列表。我在哪里可以得到这样一个列表,我在哪里加载它,并告诉链使用这个本地列表
信任验证链也存在同样的问题,因为最后一个证书应该是根证书,并且必须是受信任的根CA的客户端之一。例如,我必须加载Firefox附带的所有根CA,并检查根CA是否是其中之一?最好的方法是什么
[更新]
在google.com
示例中,我粘贴了两个完全相同的证书主题名称,这是一个复制粘贴错误
当通过HTTPS进行连接时,我会收到一个X509Certificate2对象数组,其中最下面的是服务器证书,最上面的是根CA(希望如此)
如果确实从SSL服务器获取了根ca证书,则SSL服务器配置不正确。它应该返回其服务器证书和除根CA证书之外的整个链
当我对每个证书单独调用X509Certificate2.Verify()方法时,每次都返回false
如X509Certificate2中所述。验证方法
此方法为证书构建一个简单的链,并将基本策略应用于该链。
现在什么是基本策略
我不知道。但是,ChainPolicy
的默认值之一是RevocationMode=X509RevocationMode.Online
。至于Mono,可以找到这种方法的来源。可以找到X509Chain的Mono实现源代码
这将为每个证书打印RevocationStatusUnknown和OfflineRevocation
当您指定RevocationMode=X509RevocationMode.Offline并且缓存中没有CRLs或OCSP响应(可能)时,它还应该打印什么
为了验证证书吊销,所有客户端都需要提供证书吊销列表。我在哪里可以得到这样一个列表,我在哪里加载它,并告诉链使用这个本地列表
链中的每个证书(根ca证书除外)都包含指向CRL的链接。NET和最有可能的Mono也是一个实现,它将在证书中找到指向CRL的链接,将下载它并检查证书是否被吊销
信任验证链也存在同样的问题,因为最后一个证书应该是根证书,并且必须是受信任的根CA的客户端之一。例如,我必须加载Firefox附带的所有根CA,并检查根CA是否是其中之一?最好的方法是什么
否,RevocationFlag=X509RevocationFlag.EntireChain
将使用mono使用的某些商店为您执行此操作。我不知道它是否是Firefox商店,但在Linux上它有自己的商店,您可以从Firefox商店导入根ca证书。检查ChainElements并亲自查看它找到了什么证书
我建议您仅使用SSL服务器证书构建链(因为这将向上检查链中的所有证书),并使用
RevocationMode=X509RevocationMode.Online
和RevocationFlag=X509RevocationFlag.EntireChain
。我还将尝试将X509Chain的属性设置为从SSL服务器获得的证书列表。在构建方法之后,我将使用X509Chain对象的chceck ChainStatus属性,该对象是一个状态数组。我会选择所有未设置为无错误的状态。如果有任何这样的状态,我会抛出并记录每个X509ChainStatus.status和
HTH
RevocationMode=X509RevocationMode.离线
——切换到在线。客户端必须具有本地CRL/OCSP缓存才能在脱机模式下成功验证吊销。这就是重点。我正在实现“客户机”。那么我如何提供这样的CRL。这就是我要问的问题。CRL是重试