c# - X509 证书预期用途和 SSL
问题描述
我正在考虑允许用户为我们的一项服务选择将用于 SSL 的证书,用户需要选择商店名称的初始值,并且证书列表将显示在下拉列表中,我在阅读后将其删除这篇文章认为证书应该只来自本地计算机下的MY商店位置。在检查了几篇文章后,我创建了以下代码
using (var store = new X509Store(StoreName.My,StoreLocation.LocalMachine))
{
store.Open(OpenFlags.ReadOnly);
var certificates = store.Certificates;
foreach (var c in certificates)
{
bool isSslCompatible = false;
bool ekuExists = false;//when this value does not exist, certificate can be used for all purposes [ https://tools.ietf.org/html/rfc3280#section-4.2.1.13 ]
if (c.HasPrivateKey)//only chose those that have a private key
{
foreach (X509Extension extension in c.Extensions)
{
if (extension.Oid.Value == "2.5.29.37")//[ Friedlname = Enhanced Key Usage, names are localised, firendly name cannot be used
{
ekuExists = true;
X509EnhancedKeyUsageExtension ext = (X509EnhancedKeyUsageExtension) extension;
OidCollection oids = ext.EnhancedKeyUsages;
foreach (Oid oid in oids)
{
if (/*oid.FriendlyName == "Server Authentication" || -- cannot be used as friendly names are localised*/
oid.Value == "1.3.6.1.5.5.7.3.1")
{
isSslCompatible = true;
}
}
}
}
if (isSslCompatible || !ekuExists)//add only if value is ssl compatible
{
SSLCertficate certificate = new SSLCertficate();
certificate.CertificateHash = c.GetCertHash();
certificate.CertificateHashString = c.GetCertHashString();
certificate.CertificateThumbPrint = c.Thumbprint;
certificate.FriendlyName = c.FriendlyName;
certificate.SubjectName = c.Subject;
certificate.HasPrivateKey = c.HasPrivateKey;
sslCertificates.Add(certificate);
}
}
}
上面代码的这个问题是它没有看到证书并且有所有预期的目的,我不确定如何获得这些,
检查属性窗口,我得到以下内容, 上面的代码似乎没有检测到这个证书,在 IIS 下检查,我可以将这个特定的证书用于 Https,我的代码是否缺少一些东西检测有效的 SSL 证书?
解决方案
MMC UI 有一点误导。它的意思是“启用证书已经声明的所有目的”。
在您的过滤代码中,您要求存在 EKU 扩展并具有 TLS 服务器身份验证目的。
如果存在扩展,则证书必须仅用于指定的目的之一。如果指示了多个目的,则应用程序不需要识别所有指示的目的,只要存在预期目的即可。使用应用程序的证书可能要求指明特定用途,以便该证书可以被该应用程序接受。
这通常被认为是“如果没有扩展,则证书被认为对所有目的都有效”。TLS RFC 似乎并没有专门引用id-kp-serverAuth
EKU,这意味着它是一个“通过强约定”应用程序约定来检查它。
有不同的规范覆盖“对所有目的有效”的隐式评估,例如IETF RFC 3161(可信时间戳)第 2.3 节:
相应的证书必须仅包含 [RFC2459] 第 4.2.1.13 节中定义的扩展密钥使用字段扩展的一个实例,其 KeyPurposeID 具有值:
id-kp-timeStamping。这个扩展必须是关键的。
但是,TLS 从来没有真正谈论过它。
所以你需要更复杂。Web 浏览器使用的逻辑是if (!hasEkuExtension || hasServerAuthEku)
, 与您的if (hasServerAuthEku)
.
此外,您应该(几乎)始终通过它们而不是它们来比较Oid
对象。 已本地化,因此您的代码只能在英文系统上可靠运行。该值是证书中实际内容的(文本形式)。(唯一的例外是当 Value 为 null 时,因为这意味着 API 试图表示一个没有定义 OID 的值(由于 Curve25519,这实际上只发生在 ECCurve 上))。Value
FriendlyName
FriendlyName
Oid.Value
推荐阅读
- python - 为什么我的两个 while 循环不能同时运行?
- python-3.x - 使用我自己的数据集在 Keras 中创建自定义数据生成器
- azure-sql-database - 用于创建新用户并使用数据库所有者权限登录 Azure SQL 数据库的 Terraform 代码
- python - 边值问题中的奇异雅可比行列式
- javascript - nuxt 中的许可冲突
- kotlin - 推断的类型是可为空值的集合,但预期为非可空值的集合
- amazon-web-services - 在 Alexa 技能中使用 aws-sdk
- api - 如何为 IG 媒体获取 Instagram 图像分辨率
- java - @DataJpaTest 不能排除反应性 mongo 的存储库
- c# - 使用自动映射器映射对象的问题