TLS协议分析 与 现代加密通信协议设计(四)

发表于2015-09-10
评论0 2.43w浏览

8. TLS协议的安全分析

安全分析,重中之重,也是大家最关心的。

安全分析的第一步是建立攻击模型,TLS的攻击模式是: 
* 攻击者有充足的计算资源 
* 攻击者无法得到私钥,无法得到客户端和服务器内存里面的密钥等保密信息 
* 攻击者可以抓包,修改包,删除包,重放包,篡改包。

这个模型其实就是密码学里面一般假定的攻击模型。

好了,在这个模型下,TLS的安全性分析如下:

1. 认证和密钥交换 的安全性

TLS有三种认证模式:双方认证,服务器认证,无认证。 
只要包含了有服务器端认证,就可以免疫 man-in-the-middle 攻击。但是完全匿名的会话是可以被 MITM 攻击的。匿名的服务器不能认证客户端。

密钥交换的目的,是产生一个只有通信双方知道的共享密钥 pre_master_secret 。pre_master_secret 用来生成 master_secret 。 master_secret 用来生成 Finished 消息,加密key,和MAC key。通过发送正确的Finished消息,双方可以证明自己知道正确的 pre_master_key。

1. 匿名密钥交换

匿名密钥交换是一种历史遗留的不安全方式。 匿名密钥交换缺失认证(Authentication),所以绝大多数场景下,我们应该禁用这种方式。

2. RSA 密钥交换和认证

当使用RSA的时候,合并了密钥交换 和 服务器端认证。 
RSA公钥包含在服务器证书中。要注意的是,一旦服务器证书的RSA私钥泄露,之前用该证书保护的所有流量都会变成可以破解的,即没有前向安全性(Perfect Forward Secrecy)。 
需要前向安全性的TLS用户,应该使用 DHE 或者 EC 
TLS users desiring Perfect Forward Secrecy should use DHE 类的CcipherSuite。这样,如果私钥泄露,只需要更换私钥和证书就行,不会有更大的损失。

RSA密钥交换和认证的安全性基于,在验证了服务器的证书之后,客户端用服务器的公钥加密一个 pre_master_secret 。成功地解密 pre_master_secret 并产生正确地 Finished 消息之后,就可以确信服务器拥有证书对应的私钥。

如果使用了客户端认证,通过 CertificateVerify 消息来认证客户端。客户端会签署一个之前所有握手消息的hash值,这些握手消息包括 服务器的证书,ServerHello.random 。其中服务器证书确保客户端签署了和本服务器有关的绑定(即不能重放和别的服务器的握手),ServerHello.random 确保签名和当前握手流程绑定(即不能重放)。

3. Diffie-Hellman 密钥交换和认证

当使用 DH 密钥交换的时候,服务器:

  1. 或者发送包含固定 DH参数的证书
  2. 或者发送一组临时DH参数,并用 ECDSA/RSA/DSA 证书的私钥签署。而且在签署之前,临时DH参数和 hello.random 都参与hash计算,来确保攻击者不能重放老的签名值。

无论如何,客户端都可以通过验证证书,或者验证签名,来确保收到的DH参数确实来自真正的服务器。

如果客户端有一个包含固定 Diffie-Hellman 参数的证书,则证书包含完成密钥交换所需的参数。要注意的是,这种情况下,客户端和服务器每次都会协商出相同的 DH 结果(就是 pre_master_secret)。 
为了尽可能减少 pre_master_secret 存在在内存里面的时间,当不再需要的时候,尽快将其清除,pre_master_secret 应该尽早转换成 master_secret 的形式。 
为了进行密钥交换,客户端发送的 Diffie-Hellman 参数必须和服务器发送的兼容。

如果客户端有一个标准的 DSA 或者 RSA 证书,或者 客户端没有被认证,那么客户端在ClientKeyExchange中发送一组临时参数,或者可选地发送一个CertificateVerify消息来证明自己的身份。

如果相同的 DH 密钥对,被多次用于握手协商,不管是由于客户端或服务器使用了固定DH密钥的证书,还是服务器在重用 DH 密钥,都必须小心避免 small subgroup 攻击。实现都必须遵循 rfc2785 中的标准。

最简单避免 small subgroup 攻击的方法是使用一种 DHE CipherSuite,并且每次都握手都生成一个新的 DH 私钥 X。如果选择了一个合适的base(例如2),g^X mod p 的计算可以非常快,因而性能开销会最小化。并且每次都使用一个新的DH密钥,可以提供前向安全性。当使用 DHE 类的CipherSuite时,实现必须每次握手都生成一个全新的DH私钥(即 X )。

由于TLS允许服务器提供任意的 DH 群,客户端必须确认服务器提供的DH 群的大小适合本地策略。 
客户端必须确认 DH 公共指数有足够的大小。 
如果DH群已知的话,客户端做简单比对就行了,因此服务器可以使用一个已知的群,来方便客户端的检查。

2. 版本回退攻击

由于 TLS 历史上出现过多个版本,服务器端实现可能会兼容多个版本的协议,而像 SSL 2.0 这样的版本是有严重安全问题的,因此攻击者可能会尝试诱骗客户端和服务器,来使TLS连接回退到 SSL 2.0这种老版本。

TLS 对此的解决办法,就是PreMasterSecret里面包含版本号。

3. 针对握手过程的攻击

攻击者可能会尝试影响握手过程,来使双方选择不安全的加密算法。

对这种攻击的解决办法是,如果握手消息被篡改了,那么在Finished消息里,客户端和服务器都会计算 握手消息的hash,如果攻击者篡改了握手消息,那么双方得出的hash就不一样,这样Finished消息就会验证不过。就会发现攻击。

4. 针对 Resuming Sessions 的攻击

当使用 session resuming的时候,会产生新的 ClientHello.random 和 ServerHello.random ,并和session的 master_secret 一同被hash。只要master_secret没有泄漏,并且PRF中用来生成加密key和MAC key的hash算法是安全的,连接就是安全的,并且独立于前一个连接(被恢复的前一个连接)。

只有在客户端和服务器都同意的情况下,才会做session resuming。只要有任意一方怀疑 session 泄漏,或者证书过期/被吊销,就可以要求对端做完整的握手。 
一个session的生命周期建议定位24小时。由于如果攻击者获得了 master_secret 就可以在session ID过期之前伪装成被泄漏者,所以要加一个生命期限制。 
运行在不安全环境的应用程序,不应该把session ID写入持久存储。

5. 针对应用数据保护的攻击

master_secret 和 ClientHello.random 及 ServerHello.random 一起做 hash,来生成每个连接唯一的加密key和MAC key(就算是session resuming得到的连接,也是不同的)。

在CBC和stream cipher的情况下, 
发送出去的数据,在发送前用MAC保护,来避免消息重放,避免篡改。 
MAC根据 MAC key,序列号,消息长度,消息内容,固定字符串算出。 
消息类型字段(content type)是必须的,来确保握手消息,ChangeCipherSpec消息,应用数据消息不会被混淆。 
序列号用来确保删除包或者打乱包顺序的攻击无法得逞。 
由于序列号是64位的,可以认为不会回绕。 
从一方发给对端的消息,不能被插入对端发来的字节流中,这是用于两端使用不同的 MAC key。 
类似地,server write key 和 client write key相互独立。因此stream cipher的key只使用了一次,避免了类似问题。

如果攻击者获取了加密key,那么就可以解密所有的消息。 
类似地,泄漏MAC key,会使攻击者可以篡改消息。

AEAD就简单了。

6. 显式 IV的安全性

如前文所述,TLS 1.0是把前一条消息的最后一个block,当作下一条消息的第一个IV的,这促成了2004年公开的 BEAST 攻击,后来就改成这种显式IV的更安全的方式了。

7. 加密和MAC组合模式的安全性

前文介绍CBC和AEAD时已有分析,此处略过。

8. DOS 攻击下的安全性

TLS容易遭受某些 DoS 攻击。例如,攻击者创建很多TCP连接,就可以让服务器忙于做 RSA 解密计算。然而,由于TLS运行在TCP之上,只要操作系统TCP栈的 SYN-ACK里seqnum是随机的,攻击者就无法隐藏自己的ip,这样就可以和一般的TCP连接一样做DOS防御。

由于TLS运行在TCP上,每个独立的连接都可能遭受一系列DOS攻击。尤其是,攻击者可以伪造RST包,来中断一条TCP+TLS连接。或者伪造部分TLS记录,导致连接阻塞挂起。不过这些攻击都是任何TCP协议都有问题,不是TLS特有的。

9.Session Ticket 的安全分析

Ticket必须: 1.有MAC (即 authenticated,不可篡改),2.加密(即保密)。

下面分析在各种攻击方法下的安全性。

1. 无效的Session

TLS协议要求当发现错误的时候,把TLS session变为无效。

这不会影响到ticket的安全性。

2. 窃取 Tickets

攻击者或者中间人,可能会窃取到ticket,并且尝试用来和server建立会话。 
然而,由于ticket是加密过的,并且攻击者不知道密钥,窃取到的ticket无法使攻击者恢复会话。 
TLS服务器必须使用强加密和MAC算法,来保护ticket。

3. 伪造 Tickets

一个恶意用户可能会伪造,或者篡改一个ticket,来恢复一个会话,来延长ticket的生命周期,或者假装成另一个用户。

然而,由于服务器使用了强的校验保护算法,比如带密码的 HMAC-SHA1 ,因此无法得逞。

4. DoS 攻击

推荐ticket 格式中的 key_name 字段帮助服务器有效地拒绝不是自己签发的票据。 
因此,一个攻击者可能发送大量的ticket,让服务器忙于验证ticket。 
然而,只要服务器使用了高效的加密和MAC算法,就不会有问题。(现实中,加密和MAC算法效率都极高,这根本不是问题)

5. 加密 Ticket 的key 的管理

加密ticket的key的管理,推荐的做法:

  • key 应该用密码学安全的随机数生成器生成,按照RFC4086。
  • key 和加密算法最少应该是 128 比特安全程度的。
  • key 除了加密和解密ticket以外,不应该有其他用途。
  • key 应该定期更换
  • 当ticket格式更换,或者算法更换时,应该更换key

6. Ticket 的有效期

TLS服务器控制ticket的生命周期。服务器根据配置来决定可以接受的ticket生命周期。 
ticket的生命周期可能会长于24小时。TLS客户端可能会接受到一个ticket生命周期的提示,当然,客户端本地的策略最终决定ticket保存多久。

7. 其他的 Ticket 格式和分发方法

如果没使用推荐的ticket格式,那必须小心地分析方案的安全性。尤其是,如果保密数据比如保密密钥传输给了客户端,那必须用加密方式传输,来防止泄露或篡改。

8. Identity Privacy, Anonymity, and Unlinkability

ticket的加密和加MAC,就保证了敏感信息不会泄露。

由于在ticket解密之前的TLS握手,无法隐藏客户端的特征,因此中间人可能根据相同的ticket被复用,发现相同的ticket属于相同的用户。TLS对这种情况不提供保证。

9. TLS扩展:

https://tools.ietf.org/html/rfc6066

几个比较重要的TLS扩展:

  1. Server Name Indication (SNI) 
    由于在SNI提出之前,tls握手过程中没有字段标明客户端希望连接服务器端的哪个域名,这样如果一个服务器端口上有多个域名,服务器就无法给出正确的证书。随着ipv4地址空间紧张,这个问题越发突出。因此提出了SNI。

  2. TLSEXT_ALPN 
    上层协议协商,就是在握手过程中,标明TLS里面是什么协议,例如 http2就是 h2c

  3. Maximum Fragment Length Negotiation 
    主要用于嵌入式环境,需要客户端发送。

  4. Session Ticket 
    Session Ticket,就是把session cache加密后存入客户端,这样服务器端就不需要任何存储了。

  5. TLSEXT_SAFE_RENEGOTIATION 
    重协商

  6. Certificate Status Request: 
    OCSP ,OCSP 主要是为了减少客户端查询 证书撤销列表(Ceritificate Revoke List)的网络调用,而提出的。

10. TLS的配套:PKI体系

1. X.509 证书

X.509是PKI的一个标准,其中内容包括:

  • 公钥证书
  • 证书撤销列表,CRL
  • 证书路径验证算法(CA/证书 链的格式)

X.509使用ASN.1语法做序列化/反序列化

ASN1 就是一个数据序列化/反序列化格式,跟 protobuf 差不多,可以算作竞争对手。

DER 就是用 ASN1 序列化某些数据结构的格式。

PEM 就是 DER做base64,加上一些其他字段。

证书链,以一个或多个CA证书开头的证书的列表,其中:

  • 每一个证书的 Issuer 和下一个证书的 Subject 相同
  • 每一个证书都被下一个证书的私钥签署
  • 最后一个证书是 根证书("root CA"),在TLS握手中不会被发送

证书里面包含公钥,和其它一些字段(比如证书用途,有效期,签发者等等) 
x509.v3证书的字段: 

mozilla的ca证书列表 
https://www.mozilla.org/en-US/about/governance/policies/security-group/certs/

https://www.apple.com/certificateauthority/ca_program.html 
苹果对CA提的要求:

1.CA必须取得完整的 WebTrust for Certification Authorities audit (WebTrust CA审计:http://www.webtrust.org/) 
2.你的root CA证书必须为apple平台的用户提供广泛的商业价值。例如,一个组织内内部使用的证书不能被接受为root证书。 
3.你签的证书必须含有可以公开访问的CRL地址。

Webtrust审计介绍: 
Webtrust是由世界两大著名注册会计师协会(美国注册会计师协会,AICPA和加拿大注册会计师协会,CICA)制定的安全审计标准,主要对申请对象的系统及业务运作逻辑安全性、保密性等共计七项内容进行近乎严苛的审查和鉴证。只有通过Webtrust国际安全审计认证,才有可能成为全球主流浏览器根信任的证书签发机构。

https://www.geotrust.com/ 
的网站上右下角,有个图标:  
点开就可以看到 KPMG 对 geotrust 公司的 webtrust 审计报告: 
https://cert.webtrust.org/SealFile?seal=1567&file=pdf

2011年 荷兰CA公司DigiNotar颁发假google,Facebook,微软证书被发现,后发现被入侵,导致该公司破产。 
http://www.cnbeta.com/articles/154375.htm

https://news.ycombinator.com/item?id=530600 
CA公司签署一个证书的成本是0 。 
CA公司的主要成本构成:审核 ,验证CSR成本,支持成本,法律成本(保险费用,担保费用)。 
要进入各个浏览器的根证书列表,CA公司每年必须过 WebTrust 年度审计,是很大的开销。 
一些浏览器厂商还会对植入根证书列表的CA收费。 
基础设施开销,CRL 和 OCSP 服务器成本。 
验证CSR:就是提交证书申请后,CA要做多项验证,越是高级的证书(比如EV)验证越麻烦。不固定开销,有些要花费很多人力和时间来完成。 
法律开销:CA公司得买保险,保险费跑不了。 
CA链费用:新开的CA公司要等5-10年,才会被普遍信任,才能广泛进入根证书链。要想加快点,就得给别的大牌CA公司掏钱,买次级证书。

2.现有PKI体系暴露出的问题

http://googleonlinesecurity.blogspot.com/2015/03/maintaining-digital-certificate-security.html

https://blog.mozilla.org/security/2015/04/02/distrusting-new-cnnic-certificates/

https://www.dfn-cert.de/dokumente/workshop/2013/FolienSmith.pdf

https://www.cs.utexas.edu/~shmat/shmat_ccs12.pdf

解决方案:

1. public key pin

https://developer.mozilla.org/en-US/docs/Web/Security/Public_Key_Pinning

2. HSTS

http://www.chromium.org/hsts 
收录进chrome的默认HSTS列表: https://hstspreload.appspot.com/

11. TLS协议历史上出现过的漏洞,密码学常见陷阱

1. TLS的漏洞

漏洞分析很耗时间,这里总结一些资料,有兴趣的自己看吧。

虽然TLS的设计已经尽可能的严密,但是随着技术进步的滚滚车轮,历史上还是出现过很多漏洞, 
可以参看这个rfc,做了总结:

Summarizing Known Attacks on Transport Layer Security (TLS) and Datagram TLS (DTLS)

还有这个文档: 
The Sorry State Of SSL

http://hyperelliptic.org/internetcrypto/OpenSSLPresentation.pdf

TLS 协议最近一些年被爆出过的设计缺陷,尤其是在用的最多的 AES-CBC 和 RC4 上。

AES-CBC 发现了: 
1. padding oracle 攻击 
2. BEAST 攻击 
3. Lucky 13 攻击 
4. TIME 攻击 
5. POODLE攻击

2013 年, AlFardan发表了对 RC4 的一个攻击分析,展示如何恢复 RC4 传输的连接上的数据。这种恢复攻击利用了RC4的一些已知弱点,例如RC4最初的一些字节的显著统计特征。

最近几年,TLS的代码实现引起了安全研究者的关注,这导致了新漏洞不断发现。 
2014年,OpenSSL库爆出了好几个漏洞,例如 HeartBleed,还有 CVE-2014-6321 ( Microsoft SChannel 的实现漏洞)等.

TLS的问题:

• 很多问题是由于TLS使用了一些“史前时代”的密码学算法(- Eric Rescorla) 
• CBC 和 Mac-Pad-then-Encrypt 
• RSA-PKCS#1v1.5 的 RSA padding 
• RC4 的任何使用 
• 很蠢的设计:临时 RSA 密钥协商,GOST 类CipherSuite,Snap Start 等 
• 可怕的向后兼容要求,导致迟迟不能废弃一些老算法。

The Most Dangerous Code in the World: Validating SSL Certificates in Non-Browser Software

http://crypto.stanford.edu/~dabo/pubs/abstracts/ssl-client-bugs.html

https://www.cs.utexas.edu/~shmat/shmat_ccs12.pdf

Why Eve and Mallory Love Android An Analysis of Android SSL (In)Security

2. 密码学常见陷阱

先举几个加密协议被破解的例子,给大家助兴:

网上有一些资料,有兴趣自己看吧:

密码学常见应用错误 
http://security.stackexchange.com/questions/2202/lessons-learned-and-misconceptions-regarding-encryption-and-cryptology

  • 不要自己发明加密算法。Don't roll your own crypto.
  • 不要使用不带MAC的加密 Don't use encryption without message authentication.
  • 在拼接多个字符串做hash之前,要特别小心 Be careful when concatenating multiple strings, before hashing.
  • 要特别小心使用的随机数生成器,确保有足够的熵 Make sure you seed random number generators with enough entropy.
  • 不要重用 nonce 或者。IV Don't reuse nonces or IVs.
  • 加密和MAC不要使用同样的key,非对称加密和签名不要使用相同的key Don't use the same key for both encryption and authentication. Don't use the same key for both encryption and signing.
  • 不要使用ECB模式做对称加密 Don't use a block cipher with ECB for symmetric encryption
  • Kerckhoffs定律,一个密码学系统的安全性必须建立在密码保密的基础上,其他都是公开的。Kerckhoffs's principle: A cryptosystem should be secure even if everything about the system, except the key, is public knowledge
  • 不要把用户产生的密码作为加密的key。Try to avoid using passwords as encryption keys.
  • 在密码学协议中,任何2条消息的密文都不应该一样。In a cryptographic protocol: Make every authenticated message recognisable: no two messages should look the same
  • 不要把相同的key用在通信的2个方向上。Don't use the same key in both directions.
  • 不要使用不安全的key长度。Don't use insecure key lengths.
  • ...

13. 下一代TLS: TLS 1.3

tls 1.3的草案在 http://tlswg.github.io/tls13-spec/ 
相比tls 1.2, 1.3改动巨大,这些改动对加密通信协议的一般设计也有重要启发。

TLS 1.3 的改动 
值得关注的重大改进有:

  • 0-RTT支持
  • 1-RTT握手支持
  • 改为使用HKDF做密钥拓展
  • 彻底禁止RC4
  • 彻底禁止压缩
  • 彻底禁止aead以外的其他算法
  • 去除aead的显式IV
  • 去除了AEAD的AD中的长度字段
  • 去除ChangeCipherSpec
  • 去除重协商
  • 去除静态RSA和DH密钥协商

移动互联网兴起之后,rtt延迟变得更重要,可以看到,tls 1.3 的各项改进,主要就是针对移动互联网场景的。

TLS 1.3 去掉了 ChangeCipherSpec ,这样record之上有3个协议:handshake,alert,application data

1. record层的密码学保护的改动

由于只保留了aead,所以不需要MAC key了。

aead的具体参数用法也有调整,前文有。

KDF 换成了标准的HKDF,有2种 tls_kdf_sha256, tls_kdf_sha384

2.handshake协议的改动

鉴于session ticket如此之好用,简直人见人爱,所以 TLS 1.3 直接把session ticket内置了,并改名叫 PSK

要注意的是,此 PSK 和 tls 1.2中一个很生僻的psk(见 rfc4279 )并不是一回事。

综合考虑了 session resuming ,session ticket后, 
TLS 1.3 提出了3种handshake模式:

  1. Diffie-Hellman ( 包含 DH 和 ECDH 两种,下文说到 ECDH 的地方,请自行脑补成 "ECDH/DH").
  2. A pre-shared symmetric key (PSK) ,预先共享的对称密钥,此处用统一的模型来处理session resuming 和 rfc4279的psk
  3. A combination of a symmetric key and Diffie-Hellman ,前两者合体

3.1-RTT 握手

首先,TLS 1.2 的握手有2个rtt,第一个rtt是 ClientHello/ServerHello,第二个rtt是ClientKeyExchange/ServerKeyExchange, 
之所以KeyExchange要放在第二个rtt,是由于tls1.2要支持多种密钥交换算法,和各种不同参数(比如 DH还是ECDH还是RSA,ECDHE用什么曲线,DH用什么群生成元,用什么模数,等等),这些算法和参数都依赖第一个rtt去协商出来, 
TLS1.3大刀阔斧地砍掉了各种自定义DH群,砍掉了ECDH的自定义曲线,砍掉了RSA协商,密钥协商的算法只剩下不多几个,而且其实大家实际应用中基本都用 ECDH P-256,也没啥人用别的,所以干脆让客户端缓存服务器上一次用的是啥协商算法,把 KeyExchange直接和入第一个rtt,客户端在第一个rtt里直接就用缓存的这个算法发KeyExchange的公钥,如果服务器发现客户端发上来的算法不对,那么再告诉正确的,让客户端重试好了。 
这样,就引入了 HelloRetryRequest 这个消息。

这样,基本没有副作用,就可以降到 1-RTT。 
这是TLS 1.3 的完整握手。

显然,如果一个协议只有一种密钥协商算法,比如定死为 ECDH P-256,那一定可以做到 1-RTT

4. 有副作用的 0-RTT握手

0-RTT应该是受Google的QUIC协议的启发, 
如果服务器把自己的 ECDH 公钥长期缓存在客户端,那么客户端就可以用缓存里的ECDHE公钥,构造一个电子信封,在第一个RTT里,直接就发送应用层数据了。 
这个长期缓存在客户端的ECDH公钥,称为 半静态 ECDH 公钥( semi-static (EC)DH share ) 
ECDH公钥通过 ServerConfiguration 消息发送给客户端。

这个0-rtt优化是有副作用的:

  1. 0-RTT发送的应用数据没有前向安全性。
  2. 跨连接可以重放0-RTT里的应用数据(任何服务器端无共享状态的协议,都无法做到跨连接防重放)
  3. 如果服务器端 半静态 ECDH公钥对应的私钥泄露了,攻击者就可以伪装成客户端随意篡改数据了。

服务器在 ServerConfiguration 消息里把半静态 ECDH 公钥发送给客户端。 
ServerConfiguration 值得关注一下:

  1.  struct {
  2. opaque configuration_id<1..2^16-1>;
  3.  uint32 expiration_date;
  4.  NamedGroup group;
  5. opaque server_key<1..2^16-1>;
  6.  EarlyDataType early_data_type;
  7.  ConfigurationExtension extensions<0..2^16-1>;
  8.  } ServerConfiguration;

其中的 expiration_date 是本 ServerConfiguration 最后的有效期限。 
这个值绝对不允许大于7天。 
客户端绝对不允许存储 ServerConfiguration 大于7天,不管服务器怎么填这个值。

0-RTT 中的应用数据,放在 EarlyDataIndication 中发送,

TLS 1.3 还特意给 EarlyDataIndication 定义了一种 ContentType : early_handshake 
(共四种 alert(21), handshake(22), application_data(23), early_handshake(25) )

5. Resumption 和 PSK

TLS 1.3 里面,把session resumption/session ticket 恢复出来的key,和 psk (rfc4279), 统一在一个 handshake PSK 模式下处理。

PSK CipherSuite可以 把PSK和ECDHE结合起来用,这样是有前向安全性的。 
也可以仅仅使用PSK,这样就没有前向安全性。

6. Key Schedule 过程的改动

TLS 1.3 中,综合考虑的 session ticket的各种情况后,提出了 ES,SS 两个概念,统一处理密钥协商的各种情况。 
在各种handshake模式下,ES和SS的取值来源不同。

Ephemeral Secret (ES)
每个连接新鲜的 ECDHE 协商得出的值。凡是从 ES 得出的值,都是前向安全的(当然,在 PSK only模式下,不是前向安全的)。
Static Secret (SS)
从静态,或者半静态key得出的值。例如psk,或者服务器的半静态 ECDH 公钥。

在各种 handshake 模式下:

Key ExchangeStatic Secret (SS)Ephemeral Secret (ES)
(EC)DHE (完整握手)Client ephemeral w/ server ephemeralClient ephemeral w/ server ephemeral
(EC)DHE (w/ 0-RTT)Client ephemeral w/ server staticClient ephemeral w/ server ephemeral
PSKPre-Shared KeyPre-shared key
PSK + (EC)DHEPre-Shared KeyClient ephemeral w/ server ephemeral

如上表所示:

  1. 完整的 1-RTT握手的时候, SS 和 ES 都是用的 ephemeral key ,这样是一定有前向安全性的。
  2. 使用 0-RTT 的握手的时候,使用客户端的 ephemeral key 和 服务器端的半静态 ECDH 公钥生成 SS,
  3. 纯 PSK,这种场景完全没有前向安全性,应该避免。
  4. PSK + ECDHE,这种场景比较有意思,SS是用的Pre-Shared Key,没有前向安全性,ES 用的 ephemeral key,有前向安全性。

可以看到,相比 TLS 1.2 的 session ticket,TLS 1.3 中 的 PSK + ECDHE,是结合了 ES 的,这样就有了前向安全性,相对更安全。

和 TLS 1.2 不同的是,TLS 1.3的 master_secret 是使用 ES和SS 两个得出的。

  1. HKDF-Expand-Label(Secret, Label, HashValue, Length) =
  2. HKDF-Expand(Secret, Label + '' + HashValue, Length)
  3.  1. xSS = HKDF(0, SS, "extractedSS", L)
  4.  2. xES = HKDF(0, ES, "extractedES", L)
  5.  3. master_secret = HKDF(xSS, xES, "master secret", L)
  6.  4. finished_secret = HKDF-Expand-Label(xSS,
  7.  "finished secret",
  8. handshake_hash, L)

Traffic Key Calculation

加密流量用的key,在 TLS 1.3 里面称为 Traffic Key,由于多引入了一种ContentType,在不同的ContentType下,Traffic Key 并不相同。 
如下表:

Record TypeSecretLabelHandshake Hash
Early dataxSS"early data key expansion"ClientHello
HandshakexES"handshake key expansion"ClientHello... ServerKeyShare
Applicationmaster secret"application data key expansion"All handshake messages but Finished

要关注的是, Early Data 的 Traffic Key 是用 xSS 算出来的。也就是说,是用 Pre-Shared Key决定的。因此是没有前向安全性的。

在一个TLS 连接中,究竟是用哪种 handshake 模式,是由 CipherSuite 协商决定的。

三. TLS协议的代码实现

TLS的主要实现:

  • OpenSSL
  • libressl
  • boringssl(Google)
  • libressl
  • s2n(Amazon)
  • nss(Mozilla)
  • polarssl
  • botan
  • gnutls(gpl)
  • cyassl
  • go.crypto

openssl 的 tls 协议实现有 6W 行,libressl 3.68W行, polarssl 1.29 W行, Botan 1.13 W行

openssl是其中代码最糟糕的(没有之一)。 
openssl提供了的api都太过于底层,api设计的也很费解,而且严重匮乏文档。 
请参考 《令人作呕的OpenSSL》

不幸的是,OpenSSL是用的最广泛的,是事实上的标准。

boringssl 
Google’s OpenSSL fork by Adam Langley (@agl__)

https://github.com/sweis/crypto-might-not-suck

四. TLS协议的部署与优化

这个方面网上的文章还是不少的,本文就简略一点。

全站https时代正在到来!, 
移动互联网对人们生活的介入越来越深人,用户越来越多的隐私数据和支付数据通过网络传输,人们的隐私意识安全意识不断提高;运营商流量劫持,强行插入广告越来越引起反感。因此,各互联网大厂都开始切换到https。

例如,2015年3月百度全站切换到https,百度运维部的介绍文章:《全站 https 时代的号角 : 大型网站的 https 实践系列》

不久后淘宝切了全站https,https://www.taobao.com/ 
http://velocity.oreilly.com.cn/2015/index.php?func=session&id=8

国外:由Snowden爆料,美国人发现NSA在大范围深度地监听互联网; 还有openssl连续被爆多个严重安全漏洞。之后近2年,各种加密通信协议,软件,项目开始热门,各大厂商开始关注密码协议,做数据加密,信息安全。(openssl资助,pfs被重视,)

Google的性能数据:

“In January this year (2010), Gmail switched to using HTTPS for 
everything by default. .. In order to do this we had to deploy no 
additional machines and no special hardware. On our production 
frontend machines, SSL accounts for < 1% of the CPU load, < 10 KB of 
memory per connection, and < 2% of network overhead…

If you stop reading now you only need to remember one thing: SSL is 
not computationally expensive any more.”

-- Overclocking SSL blog post by Adam Langley (Googlehttps://www.imperialviolet.org/2010/06/25/overclocking-ssl.html )

google的优化: 
https://bit.ly/gottls 
https://www.imperialviolet.org/2010/06/25/overclocking-ssl.html 
https://istlsfastyet.com/ 
https://www.ssllabs.com/downloads/SSL_TLS_Deployment_Best_Practices.pdf 
http://chimera.labs.oreilly.com/books/1230000000545/ch04.html

baidu的经验: 
http://op.baidu.com/2015/04/https-index/

aws的配置 
http://docs.aws.amazon.com/ElasticLoadBalancing/latest/DeveloperGuide/elb-https-load-balancers.html

可以参考byron之前给出的一个介绍nginx配置的文章 Nginx下配置高性能,高安全性的https TLS服务,本人提供售后咨询服务,哈哈。

CipherSuite配置(Mozilla的权威配置) 
https://wiki.mozilla.org/Security/Server_Side_TLS

hardenedlinux的这个文档:SSL/TLS部署最佳实践v1.4: 
http://hardenedlinux.org/jekyll/update/2015/07/28/ssl-tls-deployment-1.4.html

全站切https,值得关注的一个点是cdn切https,如果cdn资源不使用cdn提供商的域名的话,之前会有私钥必须得交给cdn提供商的安全风险,但是幸运的是cloudflare提出了keyless ssl方案,解决了这个问题 
https://github.com/cloudflare/keyless,cdn切https应该可以借鉴。

有时候我们会用wireshark之类的工具抓包,来调试http协议,但是切换到https后,都变成二进制密文了,直接抓包是行不通了,那怎么调试协议呢? 
有个简单的解决办法:小技巧:如何在wireshark里查看https的明文数据

五. 更多的加密通信协议case:QUIC,iMessage,TextSecure, otr, ios HomeKit,libsodium

时间有限,下面有些协议就没有做详细的分析了,读者自己去看吧。

1. QUIC

QUIC = TCP+TLS+SPDY 
https://www.chromium.org/quic

其中的 crypto design文档是本文关注的。

http://network.chinabyte.com/162/13361162.shtml 
http://blog.chromium.org/2015/04/a-quic-update-on-googles-experimental.html 
截止2015.04,从Chrome到Google server的流量的大概50% 是走的QUIC协议,而且还在不断增加。 
据说减少了YouTube的30%的卡顿。

https://github.com/devsisters/libquic

QUIC值得借鉴的地方有:crypto算法选择,0-RTT的实现方法,证书压缩省流量

QUIC的crypto算法选择: 
密钥交换算法只有2种:

  1. // Key exchange methods
  2. const QuicTag kP256 = TAG('P', '2', '5', '6'); // ECDH, Curve P-256
  3. const QuicTag kC255 = TAG('C', '2', '5', '5'); // ECDH, Curve25519

对称加密只使用AEAD,并且只有2种:

  1. // AEAD algorithms
  2. const QuicTag kNULL = TAG('N', 'U', 'L', 'N'); // null algorithm
  3. const QuicTag kAESG = TAG('A', 'E', 'S', 'G'); // AES128 + GCM-12
  4. const QuicTag kCC12 = TAG('C', 'C', '1', '2'); // ChaCha20 + Poly1305

证书类型2种,RSA证书, 和 RSA/ECDSA双证书

  1. // Proof types (i.e. certificate types)
  2. const QuicTag kX509 = TAG(‘X’, 5’, 0’, 9’); // X.509 certificate, all key types
  3. const QuicTag kX59R = TAG(‘X’, 5’, 9’, R’); // X.509 certificate, RSA keys only

handshake的结果是为了协商出来下面这些参数:

  1. // Parameters negotiated by the crypto handshake.
  2. struct NET_EXPORT_PRIVATE QuicCryptoNegotiatedParameters {
  3.  // Initializes the members to 0 or empty values.
  4.  QuicCryptoNegotiatedParameters();
  5.  ~QuicCryptoNegotiatedParameters();
  6.  QuicTag key_exchange;
  7.  QuicTag aead;
  8. std::string initial_premaster_secret;
  9. std::string forward_secure_premaster_secret;
  10.  // subkey_secret is used as the PRK input to the HKDF used for key extraction.
  11. std::string subkey_secret;
  12.  CrypterPair initial_crypters;
  13.  CrypterPair forward_secure_crypters;
  14.  // Normalized SNI: converted to lower case and trailing '.' removed.
  15. std::string sni;
  16. std::string client_nonce;
  17. std::string server_nonce;
  18.  // hkdf_input_suffix contains the HKDF input following the label: the
  19.  // ConnectionId, client hello and server config. This is only populated in the
  20.  // client because only the client needs to derive the forward secure keys at a
  21.  // later time from the initial keys.
  22. std::string hkdf_input_suffix;
  23.  // cached_certs contains the cached certificates that a client used when
  24.  // sending a client hello.
  25. std::vector<std::string> cached_certs;
  26.  // client_key_exchange is used by clients to store the ephemeral KeyExchange
  27.  // for the connection.
  28. scoped_ptr<KeyExchange> client_key_exchange;
  29.  // channel_id is set by servers to a ChannelID key when the client correctly
  30.  // proves possession of the corresponding private key. It consists of 32
  31.  // bytes of x coordinate, followed by 32 bytes of y coordinate. Both values
  32.  // are big-endian and the pair is a P-256 public key.
  33. std::string channel_id;
  34.  // Used when generating proof signature when sending server config updates.
  35.  bool x509_ecdsa_supported;
  36.  // Used to generate cert chain when sending server config updates.
  37. std::string client_common_set_hashes;
  38. std::string client_cached_cert_hashes;
  39. };

可以看到:QUIC内置支持sni 
而且区分 initial_premaster_secret 和 forward_secure_premaster_secret。

先这样吧,后续再分析。

2. apple ios iMessage

iOS Security Guide : https://www.apple.com/business/docs/iOS_Security_Guide.pdf

Apple 的 iMessage系统的密码学安全机制设计,端到端加密,前向安全(PFS),签名使用ECDSA P-256,非对称加密使用RSA 1280 bit,苹果自己维护一个 用户名--》公钥 的目录服务。

iMessage在注册时,给每个用户生成一对 RSA-1280 密钥用作非对称加密,一对 NIST P-256 ECDSA 密钥用作签名,2个私钥本地保存,公钥上传给Apple的目录服务器(IDS)。

当要发送消息的时候,根据接收方的用户名,从IDS里面找到RSA公钥 和 APNS 地址。然后随机生成 128 比特密钥,用 AES-CTR-128 加密要发送的消息,用接收方的 RSA 1280 公钥,使用 OAEP 填充加密 128比特aes密钥。然后拼接 aes密文和rsa密文,对结果使用发送方的 ECDSA 私钥,用sha1算一次数字签名。 
然后把aes密文,rsa密文,数字签名拼接起来,发给 APNS 投递给接收方。

如果要发送大文件,就生成一个key,用 aes-ctr-256 加密文件,并计算一个sha1,然后把key和sha1 放入消息里面发送。

Apple iMessage is a messaging service for iOS devices and Mac 
computers. iMessage supports text and attachments such as photos, 
contacts, and locations.Apple does not log messages or attachments, and their 
contents are protected by end-to-end encryption so no one but the 
sender and receiver can access them. Apple cannot decrypt the data. 
... 
When a user turns on iMessage on a device, the device generates two 
pairs of keys for use with the service: an RSA 1280-bit key for 
encryption and an ECDSA 256-bit key on the NIST P-256 curve for 
signing. The private keys for both key pairs are saved in the device’s 
keychain and the public keys are sent to Apple’s directory service 
(IDS), where they are associated with the user’s phone number or email 
address, along with the device’s APNs address. 
...

Users start a new iMessage conversation by entering an address or name. 
If the user enters a name, the device first utilizes 
the user’s Contacts app to gather the phone numbers and email 
addresses associated with that name, then gets the public keys and 
APNs addresses from the IDS. The user’s outgoing message is 
individually encrypted for each of the receiver’s devices. The public 
RSA encryption keys of the receiving devices are retrieved from IDS. 
For each receiving device, the sending device generates a random 
128-bit key and encrypts the message with it using AES in CTR mode. 
This per-message AES key is encrypted using RSA-OAEP to the public key 
of the receiving device. The combination of the encrypted message text 
and the encrypted message key is then hashed with SHA-1, and the hash 
is signed with ECDSA using the sending device’s private signing key. 
The resulting messages, one for each receiving device, consist of the 
encrypted message text, the encrypted message key, and the sender’s 
digital signature. They are then dispatched to the APNs for delivery. 
Metadata, such as the timestamp and APNs routing information, is not 
encrypted. Communication with APNs is encrypted using a forwardsecret 
TLS channel.

APNs can only relay messages up to 4 KB or 16 KB in size, depending 
on iOS version. If the message text is too long, or if an attachment 
such as a photo is included, the attachment is encrypted using AES in 
CTR mode with a randomly generated 256-bit key and uploaded to iCloud. 
The AES key for the attachment, its URI (Uniform Resource Identifier), 
and a SHA-1 hash of its encrypted form are then sent to the recipient 
as the contents of an iMessage, with their confidentiality and 
integrity protected through normal iMessage encryption,

3. apple ios HomeKit

iOS Security Guide : https://www.apple.com/business/docs/iOS_Security_Guide.pdf

Apple的HomeKit,是 WWDC2014 上提出的 iot 智能家居开发平台 (iot啊,目前最火的概念啊,各种高大上啊)。 
可以看到 HomeKit 作为一个全新的协议, 抛弃了历史遗留算法,直接采用了目前最先进的算法

HomeKit 密码学安全机制的设计: 
使用Ed25519做 公钥签名/验证,使用 SRP(3072 bit) 做来在iOS设备和HomeKit配件之间交换密码并做认证,使用 ChaCha20-Poly1305做对称加密, 
使用HKDF-SHA512做密钥拓展。每个session的开始用Station-to-Station 协议做密钥协商和认证, 
随后使用Curve25519做密钥协商,生成共享key。

HomeKit provides a home automation infrastructure that utilizes 
iCloud and iOS security to protect and synchronize private data 
without exposing it to Apple. 
... 
HomeKit identity and 
security are based on Ed25519 public-private key pairs. An Ed25519 key 
pair is generated on the iOS device for each user for HomeKit, which 
becomes his or her HomeKit identity. It is used to authenticate 
communication between iOS devices, and between iOS devices and 
accessories. 
... 
Communication with HomeKit accessories 
HomeKit accessories generate their own Ed25519 key pair for use in 
communicating with iOS devices. 
To establish a relationship between an iOS device and a HomeKit accessory, keys are 
exchanged using Secure Remote Password (3072-bit) protocol, utilizing 
an 8-digit code provided by the accessory’s manufacturer and entered 
on the iOS device by the user, and then encrypted using 
ChaCha20-Poly1305 AEAD with HKDF-SHA-512-derived keys. The accessory’s 
MFi certification is also verified during setup. When the iOS device 
and the HomeKit accessory communicate during use, each authenticates 
the other utilizing the keys exchanged in the above process. Each 
session is established using the Station-to-Station protocol and is 
encrypted with HKDF-SHA-512 derived keys based on per-session 
Curve25519 keys. This applies to both IP-based and Bluetooth Low 
Energy accessories.

4. TextSecure

TextSecure是一个端到端im加密通信协议,由WhisperSystem公司设计,目前whatsapp和WhisperSystem公司有合作,看网上资料,2014年11月开始,whatsapp已经开始使用TextSecure协议来做端到端加密(消息来源:https://whispersystems.org/blog/whatsapp/ 
http://www.wired.com/2014/11/whatsapp-encrypted-messaging/)。

TextSecure V2 协议: 
https://github.com/WhisperSystems/TextSecure/wiki/ProtocolV2 
https://github.com/trevp/axolotl/wiki 
https://whispersystems.org/blog/advanced-ratcheting/

The TextSecure encrypted messaging protocol 是otr的一个衍生协议,主要有2个不同点: 
1.ECDSA代替DSA 
2.某些数据结构压缩

5. otr 协议

标准文档见:https://otr.cypherpunks.ca/Protocol-v3-4.0.0.html

open kullo协议 
https://www.kullo.net/protocol/

Choice of algorithms 
Whenever we write about symmetric or asymmetric encryption or signatures, we mean the following algorithms, modes and parameters:

symmetric encryption: AES-256 in GCM mode 
asymmetric encryption: RSA-4096 with OAEP(SHA-512) padding 
asymmetric signatures: RSA-4096 with PSS(SHA-512) padding

6. libsodium/NaCL

libsodium/NaCL 值得重点介绍,大力推广 。 
新的没有兼容包袱的系统,都值得考虑用 NaCL来代替 openssl。 
libsodium是对NaCL的封装,NaCL大有来头,作者 DJB 是密码学领域的权威人物,chacha20,Curve25519 的作者 。
没有历史包袱的项目,强烈建议使用 libsodium/NaCL。

这篇文章介绍了NaCL和openssl相比的各方面改进 
http://cr.yp.to/highspeed/coolnacl-20120725.pdf 
https://cryptojedi.org/peter/data/tenerife-20130121.pdf 
http://nacl.cr.yp.to/

7. Tox.im

一款实用NaCL的端到端加密im 
https://github.com/irungentoo/toxcore/blob/master/docs/updates/Crypto.md

8. CurveCP

CurveCP值得重点介绍, 
http://curvecp.org/security.html

CurveCP的安全考量: 
Confidentiality and integrity 
server authentication? 
client authentication? 
replay attacks? 
man-in-the-middle attacks? 
passive forward secrecy? 
active forward secrecy? 
against traffic analysis? internet destination, exact timing, and approximate length of each packet that you send.

Availability availability, i.e., to make denial-of-service attacks more difficult. 
Blind amplification 
Unauthenticated memory consumption 
CPU consumption

Efficiency 
CPU overhead 
Network overhead without packet loss 
Latency without packet loss

Decongestion

9. tcpcrypt

http://tcpcrypt.org/

10.noise

https://github.com/trevp/noise/wiki

11.tcpcrypt

http://tcpcrypt.org/

12. netflix MSL

http://techblog.netflix.com/2014/10/message-security-layer-modern-take-on.html

http://www.infoq.com/cn/news/2014/11/netflix-safe-communication

12.Amazon KMS 密钥管理服务 白皮书

https://d0.awsstatic.com/whitepapers/KMS-Cryptographic-Details.pdf

值得注意和借鉴的点:

  • 对称加密算法选择了 AES-GCM-256
  • 数字签名有2种:ECDSA,RSA, 
    • ECDSA 的曲线选择了 secp384r1 (P384),hash 算法选择了 SHA384
    • RSA 选择2048位,签名体制选择 RSASSA-PSS,hash 算法选择了 SHA256
  • 密钥协商,使用ECDH,选择曲线 secp384r1 (P384),有2种用法 
    • one-pass ECDH.
    • ECDHE
  • 电子信封加密,KMS内置了电子信封。

    电子信封就是,你预先知道对方的长期公钥,你有一个消息要发送给对方,所以你生成一个随机的msgKey,然后 ciphertext = Encrypt(msgKey, message), 并且用对方的公钥加密 msgKey: encKey = Encrypt(k, msgKey), 最后把(encKey, ciphertext) 发给对方,这样,只有公钥对应私钥的拥有者才能打开信封。典型应用比如 OpenPGP。

其中的 one-pass ECDH,大概意思是: 
发起方有一对长期使用的签名密钥对,发起方生成一对临时的 ECDH 密钥,用自己的长期签名密钥签署 临时ECDH公钥。对端有一对长期 ECDH 密钥,收到发起方发来的 ECDH 公钥后,验证签名,并且用自己的长期ECDH私钥和收到的公钥协商出共享密钥。 
整个过程中,只是用了一对临时ECDH密钥,2对长期密钥。

ECDHE就是比较典型的ECDHE了,和TLS用法一样:双方都持有一对长期使用的签名密钥对,并拥有对方的签名公钥,然后分别生成一对临时ECDH密钥,用自己的签名私钥签署ECDH公钥,把得出的签名和ECDH公钥发给对方, 
双方收到对方的ECDH公钥后,验证签名,通过后用对方的ECDH公钥和自己的ECDH私钥协商出共享密钥。DONE。

白皮书中还举了几个例子,

六. TLS协议给我们的启发 -- 现代加密通信协议设计

在看了这么多的分析和案例之后,我们已经可以归纳出加密通信协议设计的普遍问题,和常见设计决策,

设计决策点:

  1. 四类基础算法 加密/MAC/签名/密钥交换 如何选择? 
    对称加密目前毫无疑问应该直接用aead,最佳选择就是 aes-128-gcm/aes-256-gcm/chacha20-poly1305了 
    数字签名/验证方案,如果是移动互联网,应该考虑直接放弃 RSA,考虑 P-256 的 ECDSA 公钥证书,或者更进一步的 ed25519 公钥证书。 
    密钥交换算法,目前最佳选择就是 curve25519,或者 P-256。

  2. 对称加密算法+认证算法,如何选择?或者直接用aead?

  3. 签名算法如何选择?RSA or ECDSA or Ed25519?

  4. 考虑将来的算法调整,要加版本号机制吗? 
    建议是加上,起码在密钥协商的步骤,要加上版本号。便于将来更新算法。

  5. RSA用作密钥交换是一个好的选择吗?考虑PFS 
    建议直接放弃RSA,RSA服务器端性能比ECDSA更差,签名更大费流量,而且没有前向安全性,给私钥保管带来更大风险。

  6. 自建PKI,是个好的选择吗?crl如何解决? 
    自建PKI可以做到更安全,比如简单的客户端内置数字签名公钥。可是当需要紧急吊销一个证书的时候,只能通过紧急发布新版客户端来解决。

  7. 必须用糟糕的openssl吗?or something better?crypto++,botan, nacl/libsodium, polarssl?libsodium: ed25519+curve2519+chacha20+poly1305

  8. 重放攻击如何解决?某种seq?或者nonce如何生成?

  9. 握手过程被中间人篡改的问题怎么解决?

  10. 性能:私钥运算的cpu消耗可以承受吗?加上某种cache? 
    要解决私钥运算的高cpu消耗,必然就需要 session ticket/session id 这种cache机制。显然session ticket 更好

  11. 延迟:密钥协商需要几个rtt?最少多少?加上cache后?和tcp对比如何

  12. TLS的性能(主要指服务器cpu消耗)还有空间可以压榨吗?我能设计一个性能更牛逼的吗?

七. 附录:密码学基础概念

本文已经很长了,基础概念的内容更多,再展开介绍就太长了,下面就列一下点,贴一下参考资料,就先这样,以后再说吧。

当然,最好的资料是下面列的书。

1. 块加密算法 block cipher

AES 等

《AES后分组密码的研究现状 及发展趋势》 
http://www.ccf.org.cn/resources/1190201776262/2010/04/15/019026.pdf

aead的介绍(作者是大神) 
https://www.imperialviolet.org/2015/05/16/aeads.html

3种组合方式之争 
http://www.thoughtcrime.org/blog/the-cryptographic-doom-principle/

CBC模式+MAC-then-encrypt的padding oracle 攻击, tls POODLE 漏洞 
http://drops.wooyun.org/papers/3194 
https://defuse.ca/blog/recovering-cbc-mode-iv-chosen-ciphertext.html

128 bit 和 256 bit key size之争 
https://www.schneier.com/blog/archives/2009/07/another_new_aes.html

nist 对 aes gcm 的技术标准,官方权威文档: 
http://csrc.nist.gov/groups/ST/toolkit/BCM/documents/proposedmodes/gcm/gcm-spec.pdf

一个gcm的调用范例 
https://github.com/facebook/conceal/blob/master/native/crypto/gcm_util.c

DES 
1天之内破解DES(2008年) 
http://www.sciengines.com/company/news-a-events/74-des-in-1-day.html

iPhone 5S开始,A7芯片也有了aes硬件指令 (ARMv8 指令集),有825%的性能提升: 
http://www.anandtech.com/show/7335/the-iphone-5s-review/4

2. 流加密算法 stream cipher

RC4,ChaCha20 等

序列密码发展现状 
http://www.ccf.org.cn/resources/1190201776262/2010/04/15/019018.pdf

rc4 : http://www.rc4nomore.com/

[RC4加密已不再安全,破解效率极高(含视频)] http://www.freebuf.com/news/72622.html

3. Hash函数 hash funtion

MD5,sha1,sha256,sha512 , ripemd 160,poly1305 等

MD5被碰撞: 
http://natmchugh.blogspot.com/2014/10/how-i-created-two-images-with-same-md5.html

http://blog.avira.com/md5-the-broken-algorithm/

4. 消息验证码函数 message authentication code

HMAC-sha256,AEAD 等

为什么要用MAC 
http://www.happybearsoftware.com/you-are-dangerously-bad-at-cryptography.html

Flickr的漏洞案例: 
http://netifera.com/research/flickr_api_signature_forgery.pdf

http://www.ietf.org/rfc/rfc2104.txt

5. 密钥交换 key exchange

DH,ECDH,RSA,PFS方式的(DHE,ECDHE)等

https://blog.cloudflare.com/a-relatively-easy-to-understand-primer-on-elliptic-curve-cryptography/

关于 前向安全性( Perfect Forward Secrecy ) 
http://vincent.bernat.im/en/blog/2011-ssl-perfect-forward-secrecy.html

http://www.cryptopp.com/wiki/Elliptic_Curve_Cryptography

google对openssl里面的椭圆曲线的优化: 
http://static.googleusercontent.com/media/research.google.com/en//pubs/archive/37376.pdf

http://www.math.brown.edu/~jhs/Presentations/WyomingEllipticCurve.pdf

ripple从nistp256k1曲线迁移到ed25519 
https://ripple.com/uncategorized/curves-with-a-twist/

openssh 6.5 开始支持 ed25519, curve25519, chacha20-poly1305 
http://www.openssh.org/txt/release-6.5

6. 公钥加密 public-key encryption

RSA,rabin-williams 等

RSA入门必读(斯坦福,普渡的课件): 
http://crypto.stanford.edu/~dabo/courses/cs255_winter07/rsa.ppt 
https://engineering.purdue.edu/kak/compsec/NewLectures/Lecture12.pdf

PKCS1 标准,应用RSA必读: 
https://www.ietf.org/rfc/rfc3447

RSA 的公钥为什么比AES的key长? 
http://crypto.stackexchange.com/questions/8687/security-strength-of-rsa-in-relation-with-the-modulus-size

http://cryptofails.blogspot.ca/2013/07/saltstack-rsa-e-d-1.html

使用什么padding? OAEP,为什么不要用PKCS V1.5

http://stackoverflow.com/questions/2991603/pkcs1-v2-0-encryption-is-usually-called-oaep-encryption-where-can-i-confirm-i

http://crypto.stackexchange.com/questions/12688/can-you-explain-bleichenbachers-cca-attack-on-pkcs1-v1-5 
http://en.wikipedia.org/wiki/Adaptive_chosen-ciphertext_attack

PKCS #1 -- #15标准协议官方网站: 
http://www.emc.com/emc-plus/rsa-labs/standards-initiatives/public-key-cryptography-standards.htm 
http://arxiv.org/pdf/1207.5446v1.pdf

blinding 一种实现上的技术,用来解决 timing 侧通道攻击的问题 
https://en.wikipedia.org/wiki/Blinding_(cryptography) 
http://crypto.stanford.edu/~dabo/papers/ssl-timing.pdf

Twenty Years of Attacks on the RSA Cryptosystem: 
http://crypto.stanford.edu/~dabo/papers/RSA-survey.pdf

电子信封(digital envelope) 
http://www.emc.com/emc-plus/rsa-labs/standards-initiatives/what-is-a-digital-envelope.htm

在openssl的evp接口中有直接支持: 
https://wiki.openssl.org/index.php/EVP_Asymmetric_Encryption_and_Decryption_of_an_Envelope

7. 数字签名算法 signature algorithm

RSA,DSA,ECDSA (secp256r1 , ed25519) 等

三大公钥体制:RSA,DSA,ECDSA 
RSA目前是主流,占据绝大多数市场份额 
DSA已经被废弃 
ECDSA是未来的趋势,例如bitcoin就用ECDSA 
https://blog.cloudflare.com/ecdsa-the-digital-signature-algorithm-of-a-better-internet/ 
https://blog.cloudflare.com/a-relatively-easy-to-understand-primer-on-elliptic-curve-cryptography/

8. 密码衍生函数 key derivation function

TLS-12-PRF(SHA-256) , bcrypto,scrypto,pbkdf2 等

hkdf: http://tools.ietf.org/html/rfc5869 
https://cryptography.io/en/latest/hazmat/primitives/key-derivation-functions/

9. 随机数生成器 random number generators

/dev/urandom 等

现代密码学实践指南[2015年]

八. 参考文献:

TLS/SSL 相关RFC及标准

协议分析文章

实际部署调优相关

密码学相关

相关开源项目


如社区发表内容存在侵权行为,您可以点击这里查看侵权投诉指引