我有一个网络应用程序,任何人都可以注册一个帐户 . 我想使用客户端证书进行身份验证,而不是密码 . 这有用吗?
好像有很多问题:
-
如何以跨浏览器方式生成密钥对?
<keygen>
似乎很有用,但我需要支持Internet Explorer . -
如何签署密钥对并将证书输入浏览器?客户端证书的每个解释仅包括用于生成证书的openssl命令 . 我真的不想从我的Web应用程序中打开openssl .
-
由于服务器正在签署证书,如果其签名(CA)密钥被泄露了怎么办?这似乎是一个比密码数据库泄漏更严重的攻击,因为攻击者可以默默地模仿任何用户 .
我想完全避免签署证书,只使用公钥指纹作为用户的身份 . 这意味着CA密钥的知识不能用于冒充任何人,因为他们没有用户的私钥 .
- 似乎有人应该以前做过这一切 . 是否有整个端到端流程的开源实现? Python或Django实现会特别有用 .
以下是我认为该过程的样子:
-
当用户注册时,他们的浏览器会生成密钥对并向服务器发送签名请求 .
-
服务器立即返回一个已加载到浏览器中的签名证书 . 服务器将密钥指纹存储在数据库中以便稍后对用户进行身份验证 . 我不想将证书DN用作身份验证,请参阅上面有关CA妥协的信息 .
-
前端Web服务器需要客户端证书,验证它们,并将公钥指纹发送到我的应用服务器 .
-
应用服务器按用户的密钥指纹查找用户,现在已经过身份验证 .
我不想处理证书撤销 . 由于密钥指纹用于验证,而不是证书DN数据,仅更改与用户关联的指纹将强制使用该密钥 .
编辑:我能够找到实现类似工作流程的演示:https://openweb.or.kr/html5/index_en.php . 它在IE中不起作用,并且我遇到了CA问题 .
1 回答
处理证书对于大多数用户来说都有学习曲线,包括在IT部门工作的人员 . 存储,移动和保护这些证书可能会很痛苦 . (我刚才在this question on Security.SE上写了一些关于这个主题的内容 . )
你可以在this question找到一些有用的指针 . 特别是,您可以在IE中使用ActiveX生成密钥对 . 然后,实现服务器端CA.在Java中,BouncyCastle对此非常有用,我想pyOpenSSL在Python中也很有用 .
确实 .
您必须签署证书才能使它们成为有效的X.509证书,但您可以调整验证这些证书的各方忽略签名并依赖公钥 . 客户端具有与证书的公钥匹配的私钥的事实由TLS握手中的
CertificateVerify
消息保证,并且它与验证证书本身的层相当独立 .Apache Httpd和Java都会让你接受证书,而不会在握手过程中验证它们(或者让你自定义如何完成),分别使用
SSLVerifyClient optional_no_ca
或空TrustManager
,但是你记得以后再进行一些验证 . 特别是,请注意不要将此应用程序与依赖于默认情况下正常PKI验证的其他应用程序混合使用处理程序,否则那些将是不安全的 .存在与所有这些相关的各种问题(特别是哪些证书颁发机构列表将由服务器发送,或者如何选择客户端证书) . 你会在this answer找到更多相关细节 .