我的组织正在寻求在我们的内部网站上使用客户端证书进行身份验证。这是一家在整个组织中使用Firefox的中型企业。
我最初看过使用Firefox的window.crypto.generateCRMFRequest()
和window.crypto.importUserCertificates()
javascript函数来生成和注册证书请求,但它们的使用看似完全没有记录。
要使window.crypto.importUserCertificates()
起作用,MDN's documentation声明任何证书必须具有相应的请求ID(假设使用generateCRMFRequest()生成)才能成功导入。我能够使用window.crypto.generateCRMFRequest()
成功生成CRMF请求,但无法弄清楚如何生成CMMF认证响应。
OpenSSL似乎不支持CRMF请求,但它可以读取ASN.1请求:
$ cat example.crmf
MIIBiDCCAYQwgesCBF7ts6IwgcmAAQKlEDAOMQwwCgYDVQQDEwN2dnamgZ8wDQYJ
KoZIhvcNAQEBBQADgY0AMIGJAoGBAME59JllBjW38By5ECaTatTd1hHY3Mrmzd+Z
pm3XrLbS8u0A4kkFozm/Yrrwzzl4w/mdJwNxuOv+5CMr3u9VFDHj5SPOgSBUlR/v
f9x9kqPVUeD21Rkv6YkS0flg8LpU22PMZgw1PtnbVXDGrkUvXr0ygF2En5ZvaL47
hhZEZn3DAgMBAAGpEDAOBgNVHQ8BAf8EBAMCBeAwFzAVBgkrBgEFBQcFAQEMCHJl
Z1Rva2VuoYGTMA0GCSqGSIb3DQEBBQUAA4GBAHx/KinpGg0+kjmF9ThduXDMuv9c
d2qE4xiCqsrEbLScCtrk+4RNnthRnQ7UXGSSwTYh/gJs0LAr4EFSvWJEnNeKNY2V
RqUD1LERr1pnTcGzZR5SCbQ6ASKqi99BgvoidAyYtAhrgLbttLIdsgHBldV8vOlL
MUi5Ya1etnfZHsTt
$ base64 -d example.crmf > example.der
$ openssl asn1parse -in example.der -inform der
0:d=0 hl=4 l= 392 cons: SEQUENCE
4:d=1 hl=4 l= 388 cons: SEQUENCE
8:d=2 hl=3 l= 235 cons: SEQUENCE
11:d=3 hl=2 l= 4 prim: INTEGER :5EEDB3A2
17:d=3 hl=3 l= 201 cons: SEQUENCE
20:d=4 hl=2 l= 1 prim: cont [ 0 ]
23:d=4 hl=2 l= 16 cons: cont [ 5 ]
25:d=5 hl=2 l= 14 cons: SEQUENCE
27:d=6 hl=2 l= 12 cons: SET
29:d=7 hl=2 l= 10 cons: SEQUENCE
31:d=8 hl=2 l= 3 prim: OBJECT :commonName
36:d=8 hl=2 l= 3 prim: PRINTABLESTRING :vvv
41:d=4 hl=3 l= 159 cons: cont [ 6 ]
44:d=5 hl=2 l= 13 cons: SEQUENCE
46:d=6 hl=2 l= 9 prim: OBJECT :rsaEncryption
57:d=6 hl=2 l= 0 prim: NULL
59:d=5 hl=3 l= 141 prim: BIT STRING
203:d=4 hl=2 l= 16 cons: cont [ 9 ]
205:d=5 hl=2 l= 14 cons: SEQUENCE
207:d=6 hl=2 l= 3 prim: OBJECT :X509v3 Key Usage
212:d=6 hl=2 l= 1 prim: BOOLEAN :255
215:d=6 hl=2 l= 4 prim: OCTET STRING [HEX DUMP]:030205E0
221:d=3 hl=2 l= 23 cons: SEQUENCE
223:d=4 hl=2 l= 21 cons: SEQUENCE
225:d=5 hl=2 l= 9 prim: OBJECT :id-regCtrl-regToken
236:d=5 hl=2 l= 8 prim: UTF8STRING :regToken
246:d=2 hl=3 l= 147 cons: cont [ 1 ]
249:d=3 hl=2 l= 13 cons: SEQUENCE
251:d=4 hl=2 l= 9 prim: OBJECT :sha1WithRSAEncryption
262:d=4 hl=2 l= 0 prim: NULL
264:d=3 hl=3 l= 129 prim: BIT STRING
这令人沮丧,因为startssl的网站对他们没有任何问题。
所以,我的问题是:服务器端必须发生什么样的魔法来处理CRMF请求并颁发可以使用window.cypto.importUserCertificates()
导入的证书?
注意:这个问题纯粹是为了好奇,我已经通过使用OpenSSL生成每个证书来解决我的身份验证问题。我的安全意识工程师并不是我完成任务的方式(特别是我生成了每个人的私钥),但没有足够的时间来修补这个问题。 :(
答案 0 :(得分:1)
如果你可以在服务器端使用Java,这里有一个Gist,它展示了如何使用BouncyCastle读取CRMF请求的内容:https://gist.github.com/503932
然后,您应该从CA的角度来看它或多或少像CSR一样(即获取公钥材料,将其绑定到您已经验证的带有身份的身份,并将捆绑包签署为证书。)
此MiniCaCertGen类中有一些示例可以颁发证书。它需要来自此script的代码,它可以工作(对于XP和Vista / 7上的IE,具有不同的API),以及使用<keygen/>
。调整代码来处理CRMF请求也不应该太困难。另外,据我记忆,Firefox仍然支持旧的<keygen/>
(并且它在HTML 5的场景中重新出现)。
您可能也对现有解决方案感兴趣,例如OpenCA。