从PEM文件获取ASN.1发行者字符串?
我最近遇到了Windows 2003的一个问题(显然它在其他版本中也存在),如果SSL / TLS服务器正在请求客户端证书身份验证,并且它具有超过16KB的受信任证书DN,Internet Explorer(或者任何其他应用)使用schannel.dll的用户)无法完成SSL握手。 (简而言之,根据RFC 2246 sec,服务器将消息分成2 ^ 14字节的块。6.2.1,但是未编写Schannel来支持该消息。我已经获得Microsoft支持的确认,这是Schannel中的缺陷,并且他们正在考虑在将来的版本中修复它。)
因此,我试图找到一种方法来轻松解析我的受信任证书(我使用Apache作为服务器,因此所有证书均为PEM格式),以获取DN的总ASN.1格式长度(这就是方法)它们在握手期间通过电线发送),从而查看我是否太接近限制了。但是,我还没有找到一种方法来执行此操作:OpenSSL asn1parse函数接近完成,但是它似乎没有提供一种仅针对发行者名称获取ASN.1序列的方法。我需要。
有什么建议?
解决方案
回答
由于ASN.1是自我描述的,因此编写ASN.1解析器相当容易。我们可能知道,ASN.1数据包含一个值树,其中每个值类型均由全局分配的OID(对象ID)标识。我们可以在以下位置找到免费的带源代码的ASN.1解码器:http://www.geocities.co.jp/SiliconValley-SanJose/3377/asn1JS.html。它是用javascript编写的,因此我们可以直接在浏览器中播放它。
关于确切问题,我会:
- 使用提供的解析器,找到另一个解析器或者编写我自己的解析器
- 查找受信任DN的OID(检查规格或者使用提供的ASN.1解码器页面简单地解码证书)
- 结合以上两者,以提取证书中受信任DN的大小。
回答
openssl asn1parse可以做到,但是我们需要进行一些手动解析来确定发行者序列的开始位置。根据RFC 5280,它是TBSCertificate序列中的第四项(如果是v1证书,则可能是第三项),紧随签名算法之后。在以下示例中:
0:d=0 hl=4 l= 621 cons: SEQUENCE 4:d=1 hl=4 l= 470 cons: SEQUENCE 8:d=2 hl=2 l= 3 cons: cont [ 0 ] 10:d=3 hl=2 l= 1 prim: INTEGER :02 13:d=2 hl=2 l= 1 prim: INTEGER :02 16:d=2 hl=2 l= 13 cons: SEQUENCE 18:d=3 hl=2 l= 9 prim: OBJECT :sha1WithRSAEncryption 29:d=3 hl=2 l= 0 prim: NULL 31:d=2 hl=2 l= 64 cons: SEQUENCE 33:d=3 hl=2 l= 11 cons: SET 35:d=4 hl=2 l= 9 cons: SEQUENCE 37:d=5 hl=2 l= 3 prim: OBJECT :countryName 42:d=5 hl=2 l= 2 prim: PRINTABLESTRING :US 46:d=3 hl=2 l= 26 cons: SET 48:d=4 hl=2 l= 24 cons: SEQUENCE 50:d=5 hl=2 l= 3 prim: OBJECT :organizationName 55:d=5 hl=2 l= 17 prim: PRINTABLESTRING :Test Certificates 74:d=3 hl=2 l= 21 cons: SET 76:d=4 hl=2 l= 19 cons: SEQUENCE 78:d=5 hl=2 l= 3 prim: OBJECT :commonName 83:d=5 hl=2 l= 12 prim: PRINTABLESTRING :Trust Anchor 97:d=2 hl=2 l= 30 cons: SEQUENCE 99:d=3 hl=2 l= 13 prim: UTCTIME :010419145720Z 114:d=3 hl=2 l= 13 prim: UTCTIME :110419145720Z 129:d=2 hl=2 l= 59 cons: SEQUENCE
发行者DN从偏移量31开始,标头长度为2,值长度为64,总长度为66个字节。当然,编写脚本并不是那么容易。