[转]现代密码学实践指南

转自:https://briteming.blogspot.com/2018/04/blog-post_97.html

本文介绍目前现代密码学的最先进技术,
前半部分主要翻译自 《Cryptographic Right Answers》,附上收集的资料,和byron个人的理解。
密码学理论艰深,概念繁多,本人知识水平有限,错误难免,如果您发现错误,请务必指出,非常感谢!


下文分类介绍在各种适用场景下,你应该使用的现代密码学算法

1. 加密数据 :

按照优先级,应该选择:
(1) 首选 NaCl库,或者libsodium库,使用里面的crypto_secretbox()/crypto_secretbox_open() 函数
(2) Chacha20-Poly1305 算法
(3) AES-GCM 算法
适用场景:当你需要避免把明文数据在网络上传输的时候。
以上3种算法,都是AEAD类的算法,AEAD是2015年最好的选择。
其中的(2)和(3)在结构上类似:一个流加密模式的算法,配合一个多项式结构的MAC。
(2)是一个流加密算法,配合一个为通用cpu优化的MAC算法,
对密码学库的实现者来说,Poly1305也比GCM更容易安全地实现。
AES-GCM是工业标准(TLS目前主要用的就是AES-GCM),现代CPU通常都有专门为AES-GCM设计的硬件指令,但是在没有硬件指令支持的CPU上(比如32位的arm),(3)性能低于(2)。
此外,应该

  • 避免AES-CBC(说来话长,后文有解释)
  • 避免AES-CTR
  • 避免64bit块大小的块加密算法--(说的就是你--BlowFish)
  • 避免OFB模式
  • 不要使用RC4,RC4已经被攻破

2. 对称密钥长度 :

选择使用256bit长度的密钥
适用场景:只要你在使用密码学,你就应该注意对称密钥长度
请记住:不要把对称加密(如AES)的key长度,和非对称加密(如RSA)的key长度搞混淆了,对称加密的key通常比非对称加密的key短多了。
下表对比了相同安全程度时,不同算法的密钥长度,单位:bit

Symmetric ECC DH/DSA/RSA
80 163 1024
112 233 2048
128 283 3072
192 409 7680
256 571 15360

此外,应该

  • 避免使用巨大key的算法(使用远大于256的key,只能说明使用者没有安全概念)
  • 避免把多个加密算法串联叠加起来使用,这并没有什么卵用
  • 避免128bit以下的key长度(比如,哥们求你别再提DES这种56bit密钥的古董了)

3. 对称签名:

应该选择 HMAC 类的算法
适用场景:安全加固一个API,如各种开放API的调用方认证
如果对一个API,你需要做认证(authenticating),但是不需要做加密(encrypting),记得千万不要自己发明算法,你自己发明的MAC算法基本都有安全漏洞,如果不信,请Google一下 "长度扩展攻击"
长度扩展攻击
Flickr的漏洞案例
同时,必须要注意的是,要使用一个常数时间字符串对比算法(这个地方和码农的常识完全相反,请务必留意)
此外,应该

  • 避免自行设计的“带密码的hash”结构,你的设计基本都是有安全漏洞的
  • 避免HMAC-MD5,避免HMAC-SHA1,使用HMAC-SHA256, HMAC-SHA512等
  • 避免复杂的多项式MAC
  • 避免加密hash值的结构
  • 避免CRC

4. Hashing/HMAC 算法

应该选择SHA2类的算法:: SHA-256, SHA-384, SHA-512, SHA-512/256
优先使用 SHA-512/256,SHA-512/256这个算法把 SHA-512 的512bit输出截短到256bit,避开了length extension 攻击。
同时,目前SHA-2是很安全可靠的,你不需要升级到SHA-3.
此外,应该

  • 避免SHA-1
  • 避免MD5
  • 避免MD6

5. 随机ID

应该使用256 bit的随机值
一定要使用 /dev/urandom,请认准这个
此外,应该

  • 避免用户空间的随机数生成器如:havaged,prngs,egd,等
  • 避免/dev/random

6. 密码处理

按照优先级顺序,选择:

  • scrypt
  • bcrypt
  • 如果以上2个都没有,那就用PBKDF2

此外,应该

  • 避免直接SHA-2
  • 避免直接SHA-1
  • 避免直接MD5

7. 非对称加密

应该使用NaCl库
适用场景:当你需要加密消息,发给陌生人,并且对方异步接收消息,做离线解密时。这是一个很窄的应用案例,这种用法有个名字叫电子信封(digital envelope),典型比如gpg加密文件后发送。
这条是几条之中最难做正确的,不要使用底层的密码学库,比如OpenSSL或者BouncyCastle。
你应该停止使用RSA,并且切换到椭圆曲线类体制,原因是:

  • 对RSA的攻击能力的进步 --- 定义在传统质数域上的乘法运算(应用包括DH,DSA,ElGamal等),要比椭圆曲线域上的乘法运算快得多。这是由于质数域上数域筛法(number field sieve,NFS)的进展,而在椭圆曲线域上,没有NFS这类算法。
  • RSA (和DH) 或迫使你考虑“向后兼容性”,而椭圆曲线体制没有这种兼容性包袱。TLS最近的几个安全漏洞,部分愿意也是由于这种向后兼容性,导致已经被破解的陈旧算法存在
  • RSA在一般场景中,都是直接用公钥做非对称加密,这种用法丧失了前向安全性(Perfect Forward Secrecy)。而椭圆曲线就不提倡,也很难这样使用,这样你就不会害死自己了。
  • 在椭圆曲线体制下,保证正确性和安全性的重任,主要由密码学家承担,密码学家会提供一组曲线参数,在某一性能水平下,针对安全性和性能做优化。这样程序员不容易误用而害死自己。在RSA体制下,正好相反,程序员必须提供参数来保证正确性和安全性,就算是RSA-OAEP这种很好的设计,程序员也必须知道怎么提供参数,这样程序员很容易搞错。

如果你必须使用RSA,一定要使用RSA-OAEP with SHA256,指数使用 65537

  • 避免 RSA-PKCS1v15
  • 避免 ElGamal
  • 避免 RSA

8. 非对称签名

应该使用NaCl,Ed25519,或者RFC6979
应用场景:如果你在设计一种新的比特币,或者一个给Ruby Gems或者Vagrant imges文件签名的系统,或者数字版权保护系统(DRM),其中一系列的文件需要离线做认证;
或者你在设计一个加密消息传输层
上一条的内容在此处全部适用。
在10+年做付费软件安全评估的工作经历中,我只有屈指可数的几次,遇到使用RSA-PSS的用户,RSA-PSS是一个学术界的推荐算法。
过去10年,非对称签名最主要的应用场景是比特币,和前向安全的密钥协商(TLS协议里面的ECDHE)。
其中最主要的算法全都是基于椭圆曲线体制的。务必警惕新出现的使用RSA签名的系统,很有可能有问题。
在过去几年中,业界有一种趋势:放弃传统DSA签名,改为难以误用的确定性签名体制,其中的EdDSA(不要和ECDSA搞混了喂!)和RFC6979是最好的例子。这种趋势的主要是受到2010年索尼PlayStation 3的 ECDSA私钥被破解事件的影响,在这个案例中,索尼公司的码农错误地把一个随机数重复使用来做ECDSA签名,形成了漏洞,使得破解者据此直接把私钥算出来了。确定性签名体制在设计中不再依赖随机数生成器,因此彻底避开此类误用。所以你应该优先使用确定性签名体制。

  • 避免RSA-PKCS1v15,避免RSA,避免ECDSA,避免DSA
  • 特别要避免常规的DSA和ECDSA

9. Diffie-Hellman 密钥交换

应该使用NaCl,Curve25519,或者DH-2048
适用场景:如果你在设计加密消息传输系统,并且无法使用固定对称密码
这是很棘手的一条,主要考量如下:

  • 如果你能使用NaCl库,那就使用NaCl库。你甚至不需要管NaCl是什么。
  • 如果你能使用一个可信赖的第三方库,那就使用Curve25519,这是一条现代的ECDH曲线,有丰富的开源代码,性能经过高度优化,被彻底地安全分析过。并且Curve25519即将进入TLS 1.3版本标准。
  • 但是绝对不要自己实现Curve25519,也绝对不要自己移植Curve25519的C代码
  • 如果你不能使用第三方ECDH库,但是可以使用DH库,那就使用DH-2048,使用1个标准的2048 bit的群。
  • 但是不要使用传统的DH,如果你需要协商DH参数,或者和其他实现互操作
  • 如果你一定要做握手协商,或者和旧软件互操作,那么考虑使用NIST P-256, NIST P-256 有广泛的软件支持。
  • 写死在代码里的DH-2048参数,比NIST P-256更安全。NIST P-256比协商出来的DH更安全。
  • 但是,由于NIST P-256的实现有一些陷阱,所以一定要谨慎选择可信赖的,广泛使用使的第三方库
  • P-256 可能是NIST曲线中最安全的,不要使用P-224。

DH(密钥协商)算法确实很难用,但是它很重要。

  • 避免,传统常规的 DH, SRP, J-PAKE 握手和协商
  • 避开任何只使用了块加密算法和srand(time())的密钥协商模式(肯定有漏洞)

10. 网站安全

应该使用OpenSSL,或者Google的BoringSSL,或者直接使用 AWS的 ELB
此处网站安全,指的是让网站支持HTTPS协议。
如果你不能把这个任务交给Amazon的云服务去做,把难题留给Amazon去解决,那么OpenSSL目前仍然是正确选择。

  • 避免不常见的TLS库,例如polarssl,GnuTLS,MatrixSSL等

11. 客户端-服务器结构的应用程序的安全

应该使用TLS
适用场景:如果你以为自己理解了前面关于公钥加密的介绍。。。
通常,在你设计了自己的RSA协议之后的1至18个月,你肯定会发现,你犯了某个错误,使你的协议没有任何安全性。
比如Salt Stack,Salt Stack的协议使用了 e=1 的RSA 公钥。。。
听起来,TLS有下面这些黑历史:

  • The Logjam DH negotiation attack
  • The FREAK export cipher attack
  • The POODLE CBC oracle attack
  • The RC4 fiasco
  • The CRIME compression attack
  • The Lucky13 CBC padding oracle timing attack
  • The BEAST CBC chained IV attack
  • Heartbleed
  • Renegotiation
  • Triple Handshakes
  • Compromised CAs

但是,你仍然应该使用TLS做传输协议,因为:

  • 这些漏洞中的大部分,仅仅是针对浏览器的,因为他们依赖受害者执行攻击者控制的JavaScript脚本,这些JavaScript脚本生成重复的明文,或特定的明文。
  • 这些漏洞中的大部分,其影响都可以被减轻,只需要你在代码和配置里面写死 TLS v1.2, ECDHE,和 AES-GCM就行。这听起来很棘手,但是这远远没有你自己设计使用ECDHE和AES-GCM的传输协议棘手。
  • 在一个自定义的传输协议的场景中,你并不需要依赖CA,你可以用一个自签名证书,嵌入到你的客户端里面。
  • 不要自己设计加密传输协议,这是极其困难而易错的工程难题
  • 使用TLS,但是不要使用默认配置

12. 在线备份

应该使用Tarsnap


名词解释

本文的内容比较新,相关中文资料极少,因此文中的名词对读者可能有点陌生,故byron这里介绍一下文中提到的一些名词:

1. NaCl库:

http://nacl.cr.yp.to/
是密码学学术权威 Daniel J. Bernstein教授 设计的一个密码学算法库,2008年发开始公布。NaCl的特点是:api简洁而易用,高性能,高安全性,主要用于网络通信,加密,解密,签名等,NaCl提供了构建高层密码学工具的核心功能。

2. libsodium库:

https://download.libsodium.org/doc/
libsodium是对NaCl库的一个分支,进一步改进接口易用性,和可移植性。

3. AEAD:

https://www.imperialviolet.org/2014/02/27/tlssymmetriccrypto.html
AEAD的概念:
在通常的密码学应用中,Confidentiality (保密) 用加密实现,Message authentication (消息认证) 用MAC实现。这两种算法的配合方式,引发了很多安全漏洞,过去曾经有3种方法:1. Encrypt-and-MAC 2.MAC-then-Encrypt 3.Encrypt-then-MAC ,后来发现,1和2都是有安全问题的,所以,2008年起,
逐渐提出了“用一个算法在内部同时实现cipher+MAC”的idea,称为AEAD(Authenticated encryption with additional data)。
在AEAD这种概念里,cipher+MAC 被 一个AEAD算法替换。
http://en.wikipedia.org/wiki/Authenticated_encryption

4. ChaCha20-poly1305

ChaCha20-poly1305是一种AEAD,提出者是Daniel J. Bernstein教授,针对移动互联网优化,目前Google对移动客户端的所有流量都使用ChaCha20-Poly1305

5. AES-GCM

AES-GCM是一种AEAD,是目前TLS的主力算法,互联网上https流量的大部分依赖使用AES-GCM。

6. AES-GCM和ChaCha20-Poly1305的性能对比测试结果:

Chip AES-128-GCM speed ChaCha20-Poly1305 speed
OMAP 4460 24.1 MB/s 75.3 MB/s
Snapdragon S4 Pro 41.5 MB/s 130.9 MB/s
Sandy Bridge Xeon (AESNI) 900 MB/s 500 MB/s

7. AES-CBC

关于AES-CBC,在AES-GCM流行之前,TLS主要依赖AES-CBC,而由于历史原因,TLS在设计之初固定选择了MAC-then-Encrypt结构,AES-CBC和MAC-then-encrypt结合,为选择密文攻击(CCA)创造了便利条件,TLS历史上有多个漏洞都和CBC模式有关:

  • The POODLE CBC oracle attack:参考:
    1.POODLE的一个分析
    2.openssl的分析
    3.乌云的文章
  • The CRIME compression attack:
  • The Lucky13 CBC padding oracle timing attack:
  • The BEAST CBC chained IV attack:

8. SHA2

http://en.wikipedia.org/wiki/SHA-2

9. Curve25519

http://cr.yp.to/ecdh.html
Curve25519 是目前最高水平的 Diffie-Hellman函数,适用于广泛的场景,由Daniel J. Bernstein教授设计。由于NIST P-256的设计过程不透明,有来历不明的参数,被广泛怀疑有后门,所以设计了Curve25519,Curve25519的设计过程完全公开,没有任何来历不明的参数。
部署情况:http://ianix.com/pub/curve25519-deployment.html

10. Ed25519

http://ed25519.cr.yp.to/
Ed25519是一个数字签名算法,

  • 签名和验证的性能都极高, 一个4核2.4GHz 的 Westmere cpu,每秒可以验证 71000 个签名
  • 安全性极高,等价于RSA约3000-bit
  • 签名过程不依赖随机数生成器,不依赖hash函数的防碰撞性,没有时间通道攻击的问题
  • 并且签名很小,只有64字节,公钥也很小,只有32字节。
    部署情况:http://ianix.com/pub/ed25519-deployment.html

11. 前向安全性

前向安全性( Perfect Forward Secrecy )
http://vincent.bernat.im/en/blog/2011-ssl-perfect-forward-secrecy.html
前向安全性指的是,如果攻击者抓取并保存流量,那么将来私钥泄露后,攻击者也无法利用泄露的私钥解密这些流量。

12. Diffie-Hellman 密钥交换

http://en.wikipedia.org/wiki/Diffie%E2%80%93Hellman_key_exchange
在任何一本密码学教材里面都会重点介绍的

13. constant time compare

针对Timing attack,http://en.wikipedia.org/wiki/Timing_attack (这种攻击真是脑洞大开!)
当一个算法的运行时间和输入数据有关的时候,可以根据运行时间这一信息,破解出密钥等。
典型的,比如要验证一个对称签名,如果你用了C库里面的memcpy(),那你就会被timing attack方式攻击。

[转]现代密码学实践指南相关推荐

  1. SSL/TLS协议原理与证书签名多种生成方式实践指南

    本章目录: 0x00 前言简述 CA 认证原理 PKI 公钥基础设施 0x01 自签名SSL证书生成 1.在线(脚本)生成 2.OpenSSL 生成 3.CFSSL 生成 0x03 cfssl 使用实 ...

  2. 《App架构师实践指南》:移动开发的进阶指南

    文章主要内容: 什么是 app 架构师 这本书主要内容 读完感受 什么是 App 架构师 成为"架构师"是许多程序员的梦想,当然也包括我,在工作的几年里,我见过很多架构师,他们在设 ...

  3. Python机器学习实践指南pdf (中文版带书签)、原书代码、数据集

    Python机器学习实践指南 目 录  第1章Python机器学习的生态系统 1  1.1 数据科学/机器学习的工作  流程 2  1.1.1 获取 2  1.1.2 检查和探索 2  1.1.3 清 ...

  4. 深度学习「CV」学习实践指南!

    ↑↑↑关注后"星标"Datawhale 每日干货 & 每月组队学习,不错过 Datawhale干货 作者:黄星源.樊亮.陈桦.斯国一 深度学习的发展不仅突破了许多视觉难题, ...

  5. json数据解析_VBA 实践指南 -- Split函数解析Json数据

    什么是JSON? JSON(JavaScript Object Notation) 是一种及其轻量级的数据交换格式,它是 ECMAScript (欧洲计算机协会制定的JavaScript规范)的一个子 ...

  6. 免费教材丨第55期:Python机器学习实践指南、Tensorflow 实战Google深度学习框架

    小编说  时间过的好快啊,小伙伴们是不是都快进入寒假啦?但是学习可不要落下哦!  本期教材  本期为大家发放的教材为:<Python机器学习实践指南>.<Tensorflow 实战G ...

  7. 《响应式Web设计:HTML5和CSS3实践指南》——2.9节基于位置伪类的交替行样式

    本节书摘来自华章社区<响应式Web设计:HTML5和CSS3实践指南>一书中的第2章,第2.9节基于位置伪类的交替行样式,作者(美) Benjamin LaGrone,更多章节内容可以访问 ...

  8. 《Core Data应用开发实践指南》一1.3 创建Grocery Dude项目

    本节书摘来自华章出版社<Core Data应用开发实践指南>一书中的第1章,第1.3节,作者 (美)Tim Roadley,更多章节内容可以访问云栖社区"华章计算机"公 ...

  9. 《术以载道——软件过程改进实践指南》—第1章1.1节对CMMI的基本认识

    本节书摘来自异步社区<术以载道--软件过程改进实践指南>一书中的第1章1.1节对CMMI的基本认识,作者任甲林,更多章节内容可以访问云栖社区"异步社区"公众号查看. 第 ...

  10. 操作系统CnetOS_7—systemd管理实践指南

    systemd管理实践指南 管理systemd CentOS 7 使用systemd替换了SysV.Systemd目的是要取代Unix时代以来一直在使用的init系统,兼容SysV和LSB的启动脚本, ...

最新文章

  1. 在Windows Server2016中安装SQL Server2016(转)
  2. Mysql 数据插入 修改删除
  3. php代码怎么修改成laravel,Laravel框架实现即点即改功能的方法分析
  4. YOLO-LITE:专门面向CPU的实时目标检测
  5. 获取当前上下文Activity
  6. [译]Quartz.NET 框架 教程(中文版)2.2.x 之第五课 SimpleTrigger
  7. 用 RSocket 解决响应式服务之间的通讯
  8. Oracle数据库以及客户端下载资源
  9. Java游戏开发中应始终坚持的10项基本原则
  10. 工程、技术与工程师三者之间的相互关系
  11. Robust Object Tracking via Sparsity-based Collaborative Model
  12. Mc模组开发--Java版的环境搭建
  13. 使用jsp+servlet来实现增加和删除功能
  14. 甘特图制定项目计划,提高项目管理效率
  15. 查看本机mac地址/ ipconfig /all 的一点笔记
  16. swustOJ 1378 Best Grass
  17. CK3M自定义伺服算法(C语言)开发的简单流程
  18. 突发!微信大更新,黄脸表情会动了,还能炸群!还有状态、浮窗...张小龙剧透的功能全来了...
  19. 手机怎么将中文翻译为英文
  20. 嘉市借互联网+打造智慧旅游 去年接待游人700万人

热门文章

  1. c语言启动程序句柄无效,win7系统玩英雄联盟突然弹出“句柄无效”窗口的解决方法...
  2. 测绘 绘图 计算机,20 机械测绘与计算机绘图 草图绘制范例 课件:草图绘制范例.pptx...
  3. Flutter动画Animation开发指南
  4. Freenom 申请免费域名(二)
  5. 前端leader找我谈心:我是如何从刚毕业的前端菜鸟一步步成长为前端工程师的?...
  6. 两个tplink路由器有线桥接_新版TP-Link路由器有线桥接怎么设置?
  7. [Error] ld returned 1 exit status
  8. 关于Id returned 1exit status的解决办法
  9. HCI超融合供应商全球六强对比
  10. android 阻尼回弹,Android ListView实现阻尼回弹效果 并去除边缘阴影