分类目录归档:Nginx

Linux系统安全_PFS/ECDH

数百万网站和数十亿网民都依靠SSL保护敏感数据如密码、信用卡号码和个人信息的传输。但最近泄漏的机密文档显示,美国国家安全局会记录大量互联网流量,储存加密数据以用于以后的密码分析。美国当然并不是唯一一个这么做的国家,沙特、中国和伊朗都是如此。保留的加密数据可以通过各种方法解密,例如法庭命令,社会工程,网站攻击,乃至密码分析。如果得到了密钥,所有相关网站的历史流量可以一次性解密。这就像打开了潘多拉的盒子。然而,互联网实际上存在应对之策——密钥协商协议Perfect Forward Secrecy(PFS),如果SSL网站的私钥泄漏,PFS可以保护以前的加密流量不会因此受到影响,因为PFS可以为每次会话分配不同密钥加密通信。PFS需要客户端浏览器和服务器端同时支持才适用。–solidot.org

但问题也不止如此,当HTTPS的网站的私钥被攻破,那么攻击者便可以很容易的制造出了中间人攻击。 这便需要一种向前的保密协议。

该协议要求,今天的秘密即使在将来的密钥被泄露,而秘密也是不被泄露的。要理解这个协议,我们首先可以从经典的TLS三次握手AES128-SHA加密套件开始,在握手期间,服务器出示证书,客户端和服务器同意主密钥。

这个过程是建立在48个字节的预置密码,是由客户端使用服务器公开的密钥进行生成和加密。然后在三次握手的过程中,客户端将密钥信息交换发送给服务器。主密钥来自客户端与服务器进行hello会话的公钥与随机值。这个方案是安全,只要服务器能够对预置的密码解密(自己的私钥)客户端发送的数据。假设,攻击者记录该服务器1年内的所有客户端和服务器之间的交流数据。2年后,服务器退役,并送往循环再造,攻击者是能够恢复出磁盘驱动器的私钥。根据这个私钥,便可以对会话进行解密。攻击者依然可以恢复密码和其他敏感信息。

现在主要的问题一个事实,私钥被用于2个目的,认证服务器加密服务共享同一个密钥。认证只是在建立通信时,而加密则持续数年之久。

为了解决这个问题的方法之一便是保持使用私钥进行验证,但是要使用一个共享密钥的独立机制。Diffie-Hellam密钥交换协议,在TLS是如何工作的呢,服务器只需要生成1次:

1 P,是一个很大的素数,

2 g,是一个原根primitive root(它能生产1~P-1所有数的一个数)

3 现设g为p的原始根,则: g mod p,g^2 mod p,…g^p-1 mod p;两两互不相同,构成一个1~p-1的全体数的一个排列。

4 对于任意数b以及素数p的原始根g,可以找到一个唯一的指数i,满足b = g^I mod p,0C=i<=p-1,则称指数i为以g为底,模p的b的离散对数。

算法描述为:

假如A和B在不安全的网络上进行协商共同的密码:

因为不安全的线路上,窃听者只能得到a,p,X,Y,除非能够计算离散对数x和y,否则将无法得到密钥k,因为k是A和B独立计算出的密钥。有Xa,Xb计算出Ya,Yb容易,但反过来由Ya,Yb计算出Xa,Xb很难。安全性上基于求有限域上求离散对数的难度。

但DH算法却容易遭中间人攻击。

为了避免中间人的攻击,构造出了基于有限域上椭圆曲线之间的同源计算问题构造细腻的公钥密码系统。

假设y^2 = X^3 + ax +b,素数p和原始根g,这些参数都是公开的,事实上,它可以有服务器生成。

利用椭圆曲线是在RFC-4492中TLS延伸的部分描述的。与经典的DH交换密钥的方法不同,在客户端和服务器端需要同意各参数。完成本协议是在客户端和服务器发送hello的消息内,虽然可以定义任意一个参数,WEB浏览器将只支持少数的预定义的曲线,通常为NIST P-256,P-384,P-521.

下面简要说一下,DH的密钥交换椭圆曲线:

 

使用ECDHE-RSA-AES128-SHA加密套件(例如P-256)已经是很程度上提高了速度。也是因为DHE-RSA-AES128-SHA缩小所涉及的各种参数的规模。

但不是所有浏览器都支持椭圆曲线加密,最近的chrome和firefox支持了NIST P-256, P-384, P-521.但大多数的IE浏览器还支持的不是很好。,最近的openssl已经加入了ECDHE密码服务套件,如果要使用64位的优化本版本,需要选择OPENSSL 1.0.1,启用ec_nistp_64_gcc_128选项。

在选择套件上,ECDHE-RSA-AES128-SHA:AES128-SHA:RC4-SHA是大多浏览器所兼容的。如果要选择PFS的方式,ECDHE-RSA-AES128-SHA,DHE-RSA-AES128-SHA,EDH-DSS-DES-CBC3-SHA。但需要确保密码套件的顺序。Nginx (1.0.6/1.1.0)是ssl_prefer_server_ciphers。Apache(2.3.3)则是SSLHonorCipherOrder。

但在使用PFS的时候,也要注意服务器端定期更新所生成的随机密钥。

Openssl的检测使用指令:openssl s_client -tls1 -cipher ECDH -connect 127.0.0.1:443

Nginx 关于PFS的代码:

使用RSA算法的时候,产生一个临时的DH密钥磋商发生,这样会话将根据这个临时的密钥加密。而证书中的密钥作为签名。这样增加了安全性。

该方法实现了OPENSSL提供的默认DH_METHD,实现了根据密钥参数生成DH公私钥,以及根据DH公钥(一方)以及DH私钥(另一方)来生成一个共享密钥,用于密钥交换。

ECDH参数不完全和DH一样,对与DH所产生参数是一个耗时的过程,所以服务器允许通过外部文件加载DH参数。ECDH的参数的形成是一套硬编码的曲线,所以参数的形成只是寻找他们,当服务器使用时,便可以加载他们。但在openssl1.0.2之前是不支持的。

可以做的是,提供ECDH参数从一个文件里读取,为了一个共同的组的一个后备。P-256是一个不错的选择则。

而这个设置不需要在服务器端进行设置,而使用的参数是有服务器端指定。