nginx实现keyless解决方案 – 作者:stan1y

简介

当企业把业务迁移到云WAF/CDN边缘节点上,需向云厂商提供业务的私钥安全性不能得到保证,且若业务私钥证书发生变化或频繁修改需要受限于人。风险:一旦服务端的私钥泄露会导致恶意攻击者伪造虚假的服务器和客户端通信,通信内容也存在被劫持和解密的风险。keyless源于clouldflare,采用keyless方案私钥部署在客户自己的服务器,无需向把业务私钥部署在云/CDN边缘节点上。

1611405699_600c1983244e1a36d4bc0.png!small?1611405694125

1611405932_600c1a6cc342367592973.png!small?1611405927816

clouldflare keyless项目地址:https://blog.cloudflare.com/keyless-ssl-the-nitty-gritty-technical-details/

cloudflare keyless开源项目地址:https://github.com/cloudflare/keyless

相关基础知识介绍:

加解密套件知识普及

MAC(Message authentication code):消息认证码

PRF(pseudorandom function):伪随机函数

SHA (Secure Hash Algorithm):安全散列算法

  • 对称密码:

DES:是以64比特的明文为一个单位来进行加密的,密钥长度是64比特

三重DES: 就是将DES重复3次,有3个密钥

AES(Advanced Encryption Standard):是一种新标准的对称密码算法,已取代DES

分组长度128比特,密钥长度128、192、256三种规格

  • 分组密码模式 :

ECB(Electronic CodeBook):将明文分组加密之后的结果将直接成为密文分组

CBC(Cipher Block Chaining):密文分组链接的模式

CFB(Cipher FeedBack):密文反馈模式

OFB(Output-Feedback):输入反馈模式

CTR(CounTeR):计数器模式

GCM(Galois Counter Mode):Galois/计数器模式

  • 填充模式:对当明文长度不为分组长度的整数倍时,需要在最后一个分组中填充一些数据使其填满一个分组长度,攻击者会利用这个利用这个在最后一个分组填充一些数据。
  • 单向散列函数

输入的是消息输出的是散列值,任意长度的消息计算出固定长度的散列值,消息不同散列值也不同

应用:MD4、MD5;SHA-2系列(SHA-256,SHA-384,SHA-512,数字表示计算后的散列值长度)

  • 密钥交换算法

RSA本质上是为了解决密钥配送的问题,密钥配送的是配送的是运算对称密钥的关键信息,并不是对称密钥

RSA:这是一个标准的密钥交换算法,在ClientKeyExchange阶段客户端生成预主秘钥,不支持向前保密,并以服务器公钥加密传送给服务器

DHE_RSA:临时Diffie-Hellman(ephemeral Diffie-Hellman, DHE),支持向前保密,缺点是执行缓慢,DHE是一种秘钥协定算法,进行协商的团体都对密钥生成产生作用,并对公共密钥产生作用

ECDHE_RSA和ECDHE_ECDSA:

临时椭圆曲线Diffe-Hellman(ephemeral elliptic curve Diffie-Hellman, ECDHE)密钥交换建立在椭圆曲线加密的基础之上。执行很快而且提供了向前保密,和DHE类似

过滤了一台设备上一天的数据

加密套件

完整名称

条数

比例

ECDHE-RSA-AES128-SHA256

TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256

590549

89.67%

DHE-RSA-AES256-GCM-SHA384

TLS_DHE_RSA_WITH_AES_256_GCM_SHA384

33802

5.13%

ECDHE-RSA-AES256-GCM-SHA384

TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384

18150

2.76%

DHE-RSA-AES256-SHA256

TLS_DHE_RSA_WITH_AES_256_CBC_SHA256

12845

1.95%

ECDHE-RSA-AES256-SHA

TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA

1462

0.22%

ECDHE-RSA-CHACHA20-POLY1305

TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256

1388

0.21%

AES256-SHA256

TLS_RSA_WITH_AES_256_CBC_SHA256

302

0.05%

ECDHE-RSA-AES128-GCM-SHA256

TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256

36

0.01%

DHE-RSA-AES256-SHA

TLS_DHE_RSA_WITH_AES_256_CBC_SHA

23

0%

AES256-SHA

TLS_RSA_WITH_AES_256_CBC_SHA

1

0%

TLS握手中使用的密码技术

TLS记录协议位于TLS协议的下层,是负责使用对称密码对消息进行加密通信(对消息压缩、加密以及数据的认证)的部分

  • TLS握手协议中使用的密码技术

公钥密码:加密预主秘钥用的

单向散列函数:构成伪随机数生成器

数字签名:验证证书用的(单向散列函数计算公钥密码的散列值,加密后得到)

伪随机书生成器:生成预主秘钥

                    生成初始化向量(可以使用对称密码,单向散列函数来构建)?

                   根据主密钥生成密钥(密码参数)?

  • TLS记录协议中使用的密码技术

对称密码(CBC模式):确保片段的机密性

消息认证码:确保片段的完整性并进行认证(单向散列函数和密钥组合而成,也可以通过对称密码生成,应用单向散列函数计算密钥+消息构成的)

认证加密(AEAD,Authenticated-Encryption with Associated-Data用于关联数据的认证加密):确保片段的完整性和机密性并进行认证?

HTTPS中所用到的密码技术

证书:公钥、数字签名和指纹组合而成,一般讲是基于指纹的数字签名,一堆的东西就认证公钥,为了保证不可否认行、认证、完整性

Keyless原理

总体架构

1611396119_600bf417e29ca5ac46d20.png!small?1611396115042

密钥交换算法类

握手协议

密钥建立

认证

RSA

RSA

RSA

DH

DH

RSA/DSA

client random 是第1个随机数R1(公开),对应wireshark抓包里“Client Hello”的Random

server random 是第2个随机数R2(公开),对应wireshark抓包里“Server Hello”的Random

premaster 是第3个随机数R3(私密),该随机数是由客户端创建,然后客户端用服务端传来的证书对premaster secret进行加密,生成premaster secret用来实际传输,对应抓包里的“Client Key Exchange”

服务端用私钥对premaster secret解密,得到premaster,这样只有客户端和服务端知道premaster

最终,客户端和服务端用公开的随机数R1、R2、双方私密的premaster(R3)组合起来,通过预定的算法生成一个hash值,作为之后的对话密钥(session key)

1611396175_600bf44f68a9fba8c550d.png!small?1611396170646

RSA密钥交换算法主密钥计算

Client Random和Server Random明文传输,中间人可以直接查看,客户端生成于中Premaster Secret后,如果有证书私钥就可以直接通过这三个参数解得主密钥

1611396224_600bf480419a9c2d9e060.png!small?1611396219433

标准RSAkeyless握手方案

工作在:Server端的ChangeCipherSpec阶段

基于DH的完整握手主密钥的计算

从密钥交换流程来说,DH算法和ECDHE一样,二者的主要区别见该页备注里的注意点1~3

client random 是第1个随机数R1(公开),对应wireshark抓包里“Client Hello”的Random ②a、server random 是第2个随机数R2(公开),对应wireshark抓包里“Server Hello”的Random

服务端自己创建一个随机数或者 直接从证书中拿公钥信息(图例是拿公钥信息),记为R3 ,结合上面的两个公开的随机数,通过DH算法算出来服务端DH参数=(R1 * R2 * R3) ,对应wireshark抓包里“Server Key Exchange”的Pubkey。

服务端用私钥,对两个公开随机数R1、R2和服务端的DH参数进行签名,对应wireshark抓包里“Server Key Exchange”的Signature

客户端用证书公钥验证Signature,验证服务端确实拥有私钥后,客户端就创建一个随机数,记为R4,通过DH算法算出来客户端DH参数=(R1 * R2 * R4) ,对应wireshark抓包里“Client Key Exchange”的Pubkey 。 这样,客户端和服务端用对方发来的DH参数,结合各自的私有随机数R3或R4,分别计算得到相同的premaster = (R1 * R2 * R3 * R4) ,且只有客户端和服务端知道premaster 最终,客户端和服务端用公开的随机数1、随机数2、双方私密的premaster组合起来,通过预定的算法生成一个hash值,作为之后的对话密钥(session key)

1611396275_600bf4b3cdf317cfc60b1.png!small?1611396271863

Server DH Parameter 是用证书私钥签名的,客户端使用证书公钥就可以验证服务端合法性,相比 RSA 密钥交换,DH 由传递 Premaster Scret 变成了传递 DH 算法所需的 Parameter,然后双方各自算出 Premaster Secret。由于 Premaster Secret 无需交换,中间人就算有私钥也无法获得 Premaster Secret 和 Master Secret。

ServerKeyExchange

基于DH的keyless的完整握手

1611396355_600bf5033a90ed460ea1d.png!small?1611396351125

工作在:Server端的ServerKeyExchange阶段

开源项目做了什么

1611396458_600bf56a473cae682339b.png!small?1611396453411

keyless server安装和配置

存储给定的私钥。

使用加速卡(EXAR)进行解密,签名操作。

状态信息统计。

开源项目地址:https://github.com/cloudflare/keyless

需要进行二次开发,开源版本很多细节处理的不好。

On Centos:

sudo yum install gcc automake libtool
sudo yum install rpm-build rubybgems ruby-devel # only required for packages
sudo gem install fpm –no-ri –no-rdoc # only required for packages

安装 make即可,make test测试

参数说明 –port keyless server端的监听端口

        –ip keyless server端监听的ip

        –server-cert和–server-key签发的证书

       –private-key-directory 用户证书对应的私钥存放文件夹

        –ca-file生成的根证书

        –pid-file pid文件

       –num-workers 线程数

      –verbose打印日志

      –daemon守护进程开启

来源:freebuf.com 2021-07-30 21:46:30 by: stan1y

© 版权声明
THE END
喜欢就支持一下吧
点赞0
分享
评论 抢沙发

请登录后发表评论