189 8069 5689

nginx怎么实现keyless

本篇内容介绍了“nginx怎么实现keyless”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!

本篇内容介绍了“nginx怎么实现keyless”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!

简介

创新互联建站成都网站建设按需设计网站,是成都网站营销公司,为白乌鱼提供网站建设服务,有成熟的网站定制合作流程,提供网站定制设计服务:原型图制作、网站创意设计、前端HTML5制作、后台程序开发等。成都网站改版热线:13518219792

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

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

TLS握手中使用的密码技术

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

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

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

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

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

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

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

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

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

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

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

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

HTTPS中所用到的密码技术

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

Keyless原理

总体架构

密钥交换算法类

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)

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

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

标准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)

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

ServerKeyExchange

基于DH的keyless的完整握手

工作在:Server端的ServerKeyExchange阶段

开源项目做了什么

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守护进程开启

nginx于keyless server交互

在SSL_do_handshake解密和签名处理过程中增加一个keyless状态。

PREPARE REQUEST状态,封装keyless请求报文,然后将状态设置为SEND REQUEST,SSL_do_handshake函数返回,nginx将keyless_connection的wev放到epoll里;

SEND REQUEST状态发送keyless请求,成功后将状态设置为RECEIVE RESPONSE,SSL_do_handshake函数返回,nginx将keyless_connection的rev放到epoll里;

RECEIVE RESPONSE状态读请求,全部读完将状态设置为FINISH;如果未读完数据SSL_do_handshake函数返回,nginx将keyless_connection的rev放到epoll里;

FINISH 继续由openssl原有的逻辑处理。

如果rev和wev超时,则关闭ssl_connection。

nginx 处理https握手

ngx_http_init_connection中recv→handler设置为ngx_http_ssl_handshake,把这个读时间加入到epoll中,重点看handshake这个函数

第一次收到client hello之后,完成初始化后调用ngx_ssl_handshake,其调用openssl的ssl_do_handshake

调用keyless模块的init函数先是获取coremodule的main conf,然后获取到servers,遍历这些servers的上下文中的srv conf配置,然后把sscf→ssl.ctx设置cert_cb为keyless_cert_handler,这个函数在api使用证书的时候会调用。

cert handler做了了很多事情,初始化了很多nginx keyless相关的参数,核心在于这个函数新建了一条通向keyserver的连接。

do handshake的时候调用的是openssl的async job的库,相当于新开一个函数栈

ASYNC JOB

先做初始化get下context,malloc一个stack,这个堆栈创建完成后把函数放进去,使用makecontext来创建一旦调用就会运行该函数,async_start_func本身使用当前job中的func,函数也是传进来的参数

Pause job最关键的是swapcontext,这个在func中一旦被调用的话,就可以立即切换栈信息,切回start_job的主函数,根据job→status=ASYNC_JOB_PAUSING来返回

切回主函数之后,因为start job是for死循环,所以会根据job的状态进行返回

返回的这个状态码,在nginx里面接到就是SSL_ERROR_WANT_ASYNC

关键就是调用async_pause_job交还给nginx来做keyless处理,以及将与keyserver的状态调整为presend。

这里处理完交还给nginx,之后nginx 就可以做原本由openssl实现的加解密。

重写engine重写两个关键函数

重写的两个函数是sign和priv_dec

调用pause时最重要逻辑是async_fibre_swapcontext,这个函数是用于切换的核心,同时进行初始化操作,把函数放到新开辟栈里运行。


名称栏目:nginx怎么实现keyless
转载来于:http://jkwzsj.com/article/ejocgh.html

其他资讯