bookmark_borderHTTPS explained (by an amateur)

厄,斯诺登传记的笔记还是没有写好。先再写一篇HTTPS的解释,因为我想实行一下费曼学习法:learn by explaining!

关于加密

加密这件事,其中算法的数学我不了解。我就先理解为一个把数据打成乱码的规则。需要一个key来加密,一个key来解密(把加密数据还原成原始信息)。加密和解密的key是同一个的话,就是对称加密。另外还有一种非对称加密,public key和private key成对,用其中之一加密的可以用另一个解密。而public key是公开的,private key必须保密。

脑中想象非常简单的对称加密:我送给你的数字都是*113的;那么你接到数字后就/113来解密。

非对称加密难以破解是基于这个事实:只知道两个大质数相乘的积要拆分出两个质数本身,对计算机来说也很难。然而生成key很容易。具体是怎么加密的我还没学会。

非对称加密的速度比对称加密慢。

关于HTTPS

HTTPS要解决的网络安全问题有两个,第一个是加密原来的HTTP信息,这样别人截获了这个信息对他们来说也无法使用。截获信息很容易。据说在公用无线网络上,同一个网络的人可以窃取你的所有请求。另外我可以想象,政府基建做好的中继路由,完全可以在上面部署程序把所有路过的信息都备份一下。(我不知道斯诺登发现的是不是NSA在这么做。。)

另一个要解决的问题是网站身份认证。如果你假装是亚马逊,然后用户就把信用卡信息填好发给你了,那么用户就完蛋了。在我自己搞HTTPS的时候我本来不理解为什么要把身份认证和加密打包在一起,因为我本来只有加密的需求。我还是觉得可以把加密和身份认证分开。当浏览器访问一个网站的时候,提醒客户这个网站只有加密没有身份认证就可以了。现在是,只有http的话浏览器会让你访问,但是有self sign(自己生成key,只有加密没有认证)的话,浏览器会不让你访问。我觉得这个是不是不太合理?(一定是我还没完全理解吧。。)如果我没有身份认证,然后我在冒充亚马逊想要套取客户的信用卡信息,那么客户可以提高警觉;但是我是一个个人博客,没有向客户索取信息,那么我完全可以不完成身份认证,客户可以随便来看看,并且知道我们交互的内容不会被ISP截取?

我那天先是试图使用自己生成的key,结果无法访问,走了很久的弯路,才知道现在浏览器都要加密和身份认证打包一起完成的。也许是为了让客户认准https标志就好了。现在好像是光是教育客户用https就挺费力的。

加密内容

加密HTTP内容是这样进行的:client端(浏览器)先获取server的public key,然后自己生成一个key用server的public key加密送给server。接下来双方的对话就用刚才送过去的key对称加密对话了。这样做的原因是非对称加密performance差,所以仅用它来交换接下来要用来对称加密的key。

第三方身份认证

如果没有身份认证,那么我可以冒充亚马逊和客户对话。我们仍然是用加密来对话,只不过客户用的是我的key,以为是亚马逊的key,然后我就获得客户的信用卡信息了。解决这个问题的办法和线下一样,第三方担保server的身份。

具体的做法是:全球有几家顶级担保机构CA (Certification Authority)(大部分是收费的;Let’s Encrypt是一家非营利机构,他们的担保服务是免费的),CA认证过网站的身份后,就开具一张证明,证明内容用CA的private key加密,而世界上任何人都可以用CA的public key解密。因为CA的private key只有CA有,所以能解密就说明这是CA开具的合法证明,就可以相信持有这个证书的网站了。

也就是说,如果想要给一个人发送绝密信息,可以用ta的public key加密,因为只有ta可以解密;如果想要全世界知道一个信息是我说的,可以用我的private key加密,把信息和public key公开,因为只有我持有我的private key,那么全世界都可以知道那个信息只有我可以写。所以private key是一个绝好的签名。

那么CA是怎么担保的呢?付费的CA我不太清楚了,他们可能有更严格的流程和定期audit什么的。Let’s Encrypt据说是要在server目录下生成什么文件,以显示你对server有权限。我操作的时候是在server上执行他们的命令,估计包括在里面了。执行的时候需要填写domain name。我可以把server配成亚马逊,不知道Let’s Encrypt会不会认证,但即使认证了,我的实际域名并不是亚马逊,我想也不会有用的。

Notes

得到了Let’s Encrypt的key之后,还要给server配置一下,这是Apache的配置

WordPress还需要(?)一个插件。其实我不是很明白它是干嘛用的:Really Simple SSL

然后要做一件事是把http的请求重定向到https。在Apache下就是在config里加一下配置。这里我并不明白80端口和443端口一个给http一个给https这个是不是约定俗成可以随便改的。(你为什么不去试一试。)

在研究这个问题的时候看到了一个博客我觉得写得很好。How does HTTPS actually workHTTPS in the real world 这两篇文章写得很好(个人博客比维基好看多了)。我特别喜欢他说,In cryptography, trust is mathematically provable. Everything else is just faith. 然后看了他描述的revoke key的问题我意识到,revoke这件事没有一个mathematical solution,所以比较麻烦。(这个问题是,CA给了你证书,然后,你的private key被人盗取了。CA证书和public key是一起发给客户端的,谁都可以截取。那么盗取你private key的人就可以拿着证书和private key冒充你了,实际上客户不该再相信这张证书。然而因为证书可以用CA的pub key解密验证的,这就没办法收回了。现行solution在文章中有,就是加入了revocation list和提供这个list的服务器。(真的没有更简单的办法了吗?)

另外想说(我也知道bash中国社会没意义,但是还是想说),因为有斯诺登和别的一些人,然后有了股沟这样的大公司发力,我们才有这个架构的,现在是相对有点安全。想想如果真的完全是局域网,如果我们的安全全都交给国内的吹哨人(不存在或者发声后被整治,见写科普文说药酒没有治病功能的人),或者国内的大企业(他们不写流氓软件已经谢天谢地了,我经常做的事情是帮我妈卸载360,而阿里腾讯什么的,如果不是有国外投资,他们出卖信息肯定是明着来的了),哦,想想就怕。啊,希望贸易战不要继续了,商业巨头丑恶,但至少还是我们和liberal世界的最后一层联系。。。

bookmark_border本站启用SSL

在发Permanent Record的读后感之前。。。

本站加上了SSL。现在可以用https访问了!

我本以为https是和一般的加密做法一样,可以自己搞个key加密一下。按照教程生成了key,放到site conf里后,浏览器说不可信。可能浏览器是想要有担保的组织给网站做担保吧?但是如果那样的话,岂不是有钱就可以了。我现在用了let’s encrypt的免费key,终于可以加密了。我的理解是加密本身要的是server-client互相交流的时候第三方不能拦截明文。至于client要不要相信server,这是一个颁证机构能担保的吗?还是需要研究。

然而。现在已经是周日晚上了。看看晚上还能做多少事吧。。

Update: 我写了一篇SSL学习笔记。。。(仍然是在写斯诺登传记读后感之前。。)