名词解释

最后更新于:2022-04-01 04:46:10

## **名词解释** 本文的内容比较新,相关中文资料极少,因此文中的名词对读者可能有点陌生,故byron这里介绍一下文中提到的一些名词: ### 1\. NaCl库: [http://nacl.cr.yp.to/](http://nacl.cr.yp.to/) 是密码学学术权威 Daniel J. Bernstein教授 设计的一个密码学算法库,2008年发开始公布。NaCl的特点是:api简洁而易用,高性能,高安全性,主要用于网络通信,加密,解密,签名等,NaCl提供了构建高层密码学工具的核心功能。 ### 2\. libsodium库: [https://download.libsodium.org/doc/](https://download.libsodium.org/doc/) libsodium是对NaCl库的一个分支,进一步改进接口易用性,和可移植性。 ### 3\. AEAD: [https://www.imperialviolet.org/2014/02/27/tlssymmetriccrypto.html](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](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的一个分析](http://www.thoughtcrime.org/blog/the-cryptographic-doom-principle/) [2.openssl的分析](https://www.openssl.org/~bodo/tls-cbc.txt) [3.乌云的文章](http://drops.wooyun.org/papers/3194) * 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](http://en.wikipedia.org/wiki/SHA-2) ### 9\. Curve25519 [http://cr.yp.to/ecdh.html](http://cr.yp.to/ecdh.html) Curve25519 是目前最高水平的 Diffie-Hellman函数,适用于广泛的场景,由Daniel J. Bernstein教授设计。由于NIST P-256的设计过程不透明,有来历不明的参数,被广泛怀疑有后门,所以设计了Curve25519,Curve25519的设计过程完全公开,没有任何来历不明的参数。 部署情况:[http://ianix.com/pub/curve25519-deployment.html](http://ianix.com/pub/curve25519-deployment.html) ### 10\. Ed25519 [http://ed25519.cr.yp.to/](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](http://ianix.com/pub/ed25519-deployment.html) ### 11\. 前向安全性 前向安全性( Perfect Forward Secrecy ) [http://vincent.bernat.im/en/blog/2011-ssl-perfect-forward-secrecy.html](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](http://en.wikipedia.org/wiki/Diffie%E2%80%93Hellman_key_exchange) 在任何一本密码学教材里面都会重点介绍的 ### 13\. constant time compare 针对Timing attack,[http://en.wikipedia.org/wiki/Timing_attack](http://en.wikipedia.org/wiki/Timing_attack) (这种攻击真是脑洞大开!) 当一个算法的运行时间和输入数据有关的时候,可以根据运行时间这一信息,破解出密钥等。 典型的,比如要验证一个对称签名,如果你用了C库里面的memcmp(),那你就会被timing attack方式攻击。 因此,涉及到密码学数据的memcmp,必须要用运行时间和输入无关的函数,比如OpenSSL库里面的`CRYPTO_memcmp()`
';

12. 在线备份

最后更新于:2022-04-01 04:46:07

## 12. **在线备份** 应该使用Tarsnap
';

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

最后更新于:2022-04-01 04:46:05

## 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,但是不要使用默认配置
';

10. 网站安全

最后更新于:2022-04-01 04:46:03

## 10. **网站安全** 应该使用OpenSSL,或者Google的BoringSSL,或者直接使用 AWS的 ELB 此处网站安全,指的是让网站支持HTTPS协议。 如果你不能把这个任务交给Amazon的云服务去做,把难题留给Amazon去解决,那么OpenSSL目前仍然是正确选择。 * 避免不常见的TLS库,例如polarssl,GnuTLS,MatrixSSL等
';

9. Diffie-Hellman 密钥交换

最后更新于:2022-04-01 04:46:01

## 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())的密钥协商模式(肯定有漏洞)
';

8. 非对称签名

最后更新于:2022-04-01 04:45:58

## 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
';

7. 非对称加密

最后更新于:2022-04-01 04:45:56

## 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
';

6. 密码处理

最后更新于:2022-04-01 04:45:54

## 6. **密码处理** 按照优先级顺序,选择: * scrypt * bcrypt * 如果以上2个都没有,那就用PBKDF2 此外,应该 * 避免直接SHA-2 * 避免直接SHA-1 * 避免直接MD5
';

5. 随机ID

最后更新于:2022-04-01 04:45:51

## 5. **随机ID** 应该使用256 bit的随机值 一定要使用 /dev/urandom,请认准这个 此外,应该 * 避免用户空间的随机数生成器如:havaged,prngs,egd,等 * 避免/dev/random
';

4. Hashing/HMAC 算法

最后更新于:2022-04-01 04:45:49

## 4. **Hashing/HMAC 算法** 应该选择[SHA2](http://en.wikipedia.org/wiki/SHA-2)类的算法:: 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
';

3. 对称签名

最后更新于:2022-04-01 04:45:47

## 3. **对称签名**: 应该选择 HMAC 类的算法 适用场景:安全加固一个API,如各种开放API的调用方认证 如果对一个API,你需要做认证(authenticating),但是不需要做加密(encrypting),记得千万不要自己发明算法,你自己发明的MAC算法基本都有安全漏洞,如果不信,请Google一下 “长度扩展攻击” [长度扩展攻击](http://en.wikipedia.org/wiki/Length_extension_attack) [Flickr的漏洞案例](http://netifera.com/research/flickr_api_signature_forgery.pdf) 同时,必须要注意的是,要使用一个**常数时间字符串对比算法**(这个地方和码农的常识完全相反,请务必留意) 此外,应该 * 避免自行设计的“带密码的hash”结构,你的设计基本都是有安全漏洞的 * 避免HMAC-MD5,避免HMAC-SHA1,使用HMAC-SHA256, HMAC-SHA512等 * 避免复杂的多项式MAC * 避免加密hash值的结构 * 避免CRC
';

2. 对称密钥长度

最后更新于:2022-04-01 04:45:45

## 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密钥的古董了)
';

1. 加密数据

最后更新于:2022-04-01 04:45:42

## 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已经被攻破
';

前言

最后更新于:2022-04-01 04:45:40

> 原文:https://blog.helong.info/blog/2015/06/05/modern-crypto/ > 作者:byronhe 本文介绍目前现代密码学的最先进技术, 前半部分主要翻译自 [《Cryptographic Right Answers》](https://gist.github.com/tqbf/be58d2d39690c3b366ad),附上收集的资料,和byron个人的理解。 密码学理论艰深,概念繁多,本人知识水平有限,错误难免,如果您发现错误,请务必指出,非常感谢! >[info] #### 下文分类介绍在各种适用场景下,你应该使用的现代密码学算法
';