分类于 PKI, 代码人生 | 748 次点击 | 评论(3) »
由 Apex 发表于

自从六年前我从ASP阵营弃暗投明转向PHP阵营之后,就不时的与Apache打交道,Apache的配置也从1.3研究到2.2版。但是有一个问题一直困扰我,而且它不定时的就冒出来打击我一下,让我很是郁闷。

这个问题是这样的:把网站设置为需要进行SSL双向认证(即通过https://的方式访问网站,还需要有客户端数字证书),如果服务端是基于Apache的话,那么客户端(也就是浏览器)每次访问一个页面,对于页面上的每一份资源(一个页面通常包含很多资源,例如被html页面引用的.js/.css文件,页面中的各个图片、flash等等),都需要做一次数字签名。奇怪的是IIS服务器就没有这种情况。

每访问一个资源就做一次数字签名,这是一件恐怖的事情。一般情况下一个html页面都会包含十几个甚至几十个资源(特别是一些装饰用的小图片和一些小图标等等,每个文件也就两三KB,但是也需要进行数字签名),早期使用数字证书的时候基本上都是将数字证书保存在计算机硬盘上,数字签名也是由CPU来进行,一次数字签名也就几个毫秒,看起来影响就不大,但是随着技术的发展,后来都是以USB Key来对数字证书进行存储和运算,为了安全,数字签名就只能USB Key内部进行。试想一下,处理器速度一般就几M,高的也就几十M的USB Key处理芯片,在做数字签名的时候效率比起计算机两三个G的运算速度低了不少,即使经过特别优化,一般的USB Key做一次数字签名也需要十多二十毫秒。这种情况下,每访问一个资源就需要做一次数字签名,在打开一个网页的时候,就会发现有明显的延时,现象就是页面文字都已经显示出来了,而USB Key的指示灯还在狂闪(USB Key上通常有一个指示灯,当USB Key正在工作的时候就会闪烁,以提醒用户),然后才能够看到页面上的图片内容一个一个的显示出来。

这几年里,对于这个问题我一直都不求甚解,当初想通过修改Apache配置来解决,也试图在PHP脚本中加入Keep-alive之类的标记,但是终不得其法,渐渐的也就有了一个错误的认识,那就是Apache无法做到SSL状态的缓存,客户端访问每个SSL资源都必须重新重新经历握手、产生会话密钥等过程,所以每访问一个资源就会做一次数字签名。

这个错误的认识一直延续了好几年,在这几年中,当有人问到我这方面的问题时,我都毫不犹豫的告诉他这是Apache的问题,是出于安全性考虑才这样做的。但是另一方面,在我内心深处,还是隐约觉得事情不应该是这样的。终于,在一次封闭开发的过程中,我弄明白了事情的真相。
阅读这篇日志的剩余部分 »