security - 唯一标识用户时使用客户端证书的哪些部分?

标签 security authentication x509certificate pki

我正在设计一个系统,除了用户名/密码身份验证之外,用户还可以注册并随后使用客户端证书进行身份验证。

客户端证书必须是由配置的证书颁发机构列表颁发的有效证书,并且在提交时将进行检查(验证)。

在注册阶段,我需要将部分客户端证书存储在用户存储库(DB、LDAP 等)中,以便我可以将使用客户端证书进行身份验证的用户映射到内部“用户”。

一个相当明显的选择是使用证书指纹;但指纹本身还不够,因为可能会发生冲突(即使它们不太可能发生),因此我们需要存储证书中的附加信息。 This SO question在这方面也提供了丰富的信息。

RFC 2459定义 (4.1.2.2) 证书序列号在给定 CA 内必须是唯一的。

将所有这些结合起来,我正在考虑存储每个注册用户的证书序列号和证书颁发者。鉴于客户端证书将被验证并且有效,这应该唯一地标识每个客户端证书。这样,即使客户端证书更新,它仍然有效(序列号保持不变,颁发者也保持不变)。

我错过了什么吗?

最佳答案

您有几种解决方案:

  1. 存储指纹。 是的,你是对的,理论上可能会发生冲突,但概率确实非常低,你可以认为它不会发生:系统中的 2 个用户不会意外地拥有相同的证书指纹。然而,随着时间的推移,哈希算法变得越来越弱,攻击者可能会尝试伪造指纹与注册指纹匹配的证书。这种攻击称为第二原像攻击,很难做到,因为攻击者不会尝试伪造一些与指纹匹配的随机数据,而是伪造一个可以通过初始验证阶段(即破解 PKI)的真实 X.509 证书。相当困难:)但如果您真的想防止碰撞,您可以使用 2 种不同的算法(例如 SHA-1 和 SHA-256)存储 2 个指纹。

  2. 存储证书颁发者和序列号。是的,它可以用作唯一的证书标识符。正如您所写,标准( RFC 5280 废弃 RFC 2459)指示[序列号]对于给定 CA 颁发的每个证书必须是唯一的。但这也意味着当证书续订时自 CA 颁发新证书以来,序列号发生变化。

最后一句话:您想要处理证书更新,这是一个好主意,很多软件编辑器忘记了证书必须更新。但你必须意识到,证书中几乎所有内容都可能发生变化:主体名称(人们可能会更改名称、女性结婚……)、颁发者名称(证书供应商公司可能会更改……)、 key 算法、 key 大小、扩展名...在您的系统中,证书续订过程可能与初始用户证书注册过程非常接近。

关于security - 唯一标识用户时使用客户端证书的哪些部分?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5290571/

相关文章:

android - 使用 Jetpack 的 EncryptedSharedPreferences 和 EncryptedFile 有什么好处?

security - WSO2 ESB 获取认证名称

java - X.509 使用指纹验证 key 链

C# SSL服务器模式必须使用带有对应私钥的证书

java - Android 的 HSTS 或 ATS 等效项?

mysql - MySQL表的主键应该暴露吗?

c# - OpenId 身份验证跳过 "Please wait..."屏幕

php - 用户应该成为 Laravel 中的资源吗?

java - android 如何处理url中的空格

java - 如何将证书文件添加/转换为 pkcs12 文件