本站总访问量
文章目录
  1. 1. 例子1:TLS的设计
  2. 2. 例子2:某xx协议
    1. 2.1. 首先,介绍一下ECDH
    2. 2.2. 再介绍一个陷阱
    3. 2.3. 然后,科普一下什么是HMAC
    4. 2.4. 另外,还有一些坑要注意:
    5. 2.5. 最后给出一些算法的性能
    6. 2.6. 怎么样防重放?

如何设计一次可靠的通信呢?

安全可靠的保障:

  1. 对称加密以及非对称加密来解决:保密性
  2. 数字签名:认证、不可抵赖
  3. 单向Hash算法:完整性

tx

这幅图看懂了吗?

例子1:TLS的设计

TLS的设计目标是构建一个安全传输层(Transport Layer Security ),在基于连接的传输层(如tcp)之上提供:

1.密码学安全

保密, message privacy (保密通过加密encryption实现,所有信息都加密传输,第三方无法窃听 )
完整性, message integrity( 通过MAC校验机制,一旦被篡改,通信双方会立刻发现 )
认证, mutual authentication (双方认证,双方都可以配备证书,防止身份被冒充 )

2.互操作,通用性 ( 根据公开的rfc,任何符合rfc的软件实现都可以互操作,不受限于任何专利技术)
3.可扩展性 ( 通过扩展机制 tls_ext可以添加功能,有大量的新功能,都是通过扩展添加的)
4.高效率 (通过session cache,恰当部署cache之后,tls的效率很高)

TLS的设计和实现,可以看我同事byronhe写的一篇博文,这里不展开,请继续往下看。
http://blog.helong.info/blog/2015/09/06/tls-protocol-analysis-and-crypto-protocol-design/

例子2:某xx协议

1.借鉴TLS的设计,用非对称加密算法来协商通信密钥,对称加密算法来加密通信数据
2.同wx的xxoo协议实现不一样,双保险,增加破解成本
3.关注性能,越简单越好
4.考虑异常情况下的处理,支持随时降级。

使用优化后的ECDH+ECDSA算法来密钥协商,自研的xxx+HMAC来加解密,支持用户证书认证,防中间人和防重放。

下面分享几个关键点。

首先,介绍一下ECDH

ECDH是基于ECC(Elliptic Curve Cryptosystems,椭圆曲线密码体制,参看ECC)的DH( Diffie-Hellman)密钥交换算法。交换双方可以在不共享任何秘密的情况下协商出一个密钥。ECC是建立在基于椭圆曲线的离散对数问题上的密码体制,给定椭圆曲线上的一个点P,一个整数k,求解Q=kP很容易;给定一个点P、Q,知道Q=kP,求整数k确是一个难题。ECDH即建立在此数学难题之上。

简单来说,两端生成公私钥对,然后分别把自己的公钥传输给对方,最后双方通过ECDH_compute_key这个函数计算出相同的key。

tx2

先看图吧,看不懂再看下面这个例子:

客户端随机生成client[pri]、client[pub]
后台随机生成server[pri]、server[pub]
双方交换公钥,私钥自己保存
客户端key = ECDH_compute_key(client[pri],server[pub])
后台key = ECDH_compute_key(server[pri],client[pub])
此时双方就协商出一个相等的key了,这个key可以作为根密钥派生出对称加密密钥。

采用ECDH协商,协商过程中信道只会传输密钥材料,不会传输最终的key,比传统的【A端生成RSA公私钥对,然后把公钥给B端,B端随机生成key并传输RSA(key,pub)给A,A用pri来解密获得key】的方式要安全。但ECDH不能防中间人,需要加上签名认证算法,如ECDSA来保障。

再介绍一个陷阱

在密码学历史上,出现过3种加密和认证的组合方式:

Encrypt-and-MAC:加密后加上原串MAC
MAC-then-Encrypt:把(原串和原串MAC)加密
Encrypt-then-MAC:原串加密后,再整体MAC

在TLS协议初定的那个年代,人们还没意识到这3种组合方式的安全性有什么差别,所以TLS协议规定使用 MAC-then-Encrypt,即先计算MAC,然后把 “明文+MAC” 再加密(块加密或者流加密)的方式,做流加密+MAC,和块加密+MAC。

但是,悲剧的是,近些年,人们发现 MAC-then-Encrypt 这种结构导致了 很容易构造padding oracle 相关的攻击,例如这在TLS中,间接形成被攻击者利用,这间接导致了 BEAST 攻击 , Lucky 13攻击 (CVE2013-0169) 和 POODLE 攻击 (CVE2014-3566)。
目前因此,学术界已经一致同意: Encrypt-then-MAC才是最安全的!
tls使用的是 MAC-then-Encrypt的模式,导致了一些问题。具体比较,参见:
http://cseweb.ucsd.edu/~mihir/papers/oem.pdf
https://www.iacr.org/archive/crypto2001/21390309.pdf
http://crypto.stackexchange.com/questions/202/shouldwemacthenencryptorencryptthenmac
https://news.ycombinator.com/item?id=4779015
http://tozny.com/blog/encryptingstringsinandroidletsmakebettermistakes/

鉴于这个陷阱如此险恶,学术界有人就提出了,干脆把Encrypt和MAC直接集成为一个算法,在算法内部解决好安全问题,不再让码农选择,避免众码农再被这个陷阱坑害,这就是AEAD(Authenticated Encryption With Addtional Data)类的算法,GCM模式就是AEAD最重要的一种。如果常用的AES-GCM。

然后,科普一下什么是HMAC

HMAC是密钥相关的哈希运算消息认证码(Hash-based Message Authentication Code),HMAC运算利用哈希算法,以一个密钥和一个消息为输入,生成一个消息摘要作为输出。常用的HAMC有HMAC-MD5和HMAC-SHA。

算法公式 : HMAC(K,M)=H(K⊕opad∣H(K⊕ipad∣M))

H 代表所采用的HASH算法(如SHA-256)
K 代表认证密码
Ko 代表HASH算法的密文
M 代表一个消息输入
B 代表H中所处理的块大小,这个大小是处理块大小,而不是输出hash的大小

一次HMAC运算相当于计算了两次HASH。所以,一般来说,HMAC的性能是HASH算法的一半。

另外,还有一些坑要注意:

正确的签名方式是,经过密码学HASH后,对HASH结果进行签名,这样的实现能保证签名有效性。
算法实现应该使用开源密码学库,不要自己搞
CBC操作模式的iv一定要通过随机数生成器生成

最后给出一些算法的性能

在E5-2420@1.90GHz单核下使用openssl 1.0.2a测试:

ecdsa_sign—_256: 1.2w次/s(签名串71B)
ecdsa_verify_256:5100次/s
RSA2048_sign:545.3次/s(签名串256B)
RSA2048_verify:1.8w次/s
ECDH_compute_key_256: 7100次/s(32B)

这里看出,ECDSA签名快验证慢,RSA是签名慢验证快。在协商环节,如果后台签名客户端验签,则后台使用ecdsa比较好。另外ECDSA256签名生成的签名串长71B,比RSA2048的256B短多了,能有效减少报文大小,减少流量消耗。

怎么样防重放?

这里先卖个关子,大家可以思考一下,要考虑通信过程中的丢包哦:)

总结一下,设计可靠的通信协议,如果只考虑密码学安全是不够的,还要综合考虑性能和流量。密码学安全,在设计和实现上稍有不当,很容易踩坑,所以还是尽量使用开源的标准实现吧。本文如有错漏,请斧正。

据说新的chacha20-poly1305很不错,是AEAD算法,而且在ARM架构下性能很好,实测了在TS8单核有130M/s。

TEA+HMAC-SHA256:60MB/s
AES-GCM:400MB/s(AES-NI下700MB/s)
Chacha20-poly1305:130MB/s
测试环境:TS8-Xeon E5-2420@ 1.90GHz单核-openssl 1.0.2a /libsodium 1.0.11

文章目录
  1. 1. 例子1:TLS的设计
  2. 2. 例子2:某xx协议
    1. 2.1. 首先,介绍一下ECDH
    2. 2.2. 再介绍一个陷阱
    3. 2.3. 然后,科普一下什么是HMAC
    4. 2.4. 另外,还有一些坑要注意:
    5. 2.5. 最后给出一些算法的性能
    6. 2.6. 怎么样防重放?