【密码学简介】
很多人都误用了密码学
一般可归为三类:
1. 愚蠢
比如Google Keyczar(计时旁路 timing side channel),SSL(对话重建 session renegotiation)
2. 工具使用方法错误
亚马逊AWS signature method 1(non-collision-free signing),Flickr API signatures(hash length-extension)
3. 不寻常的环境
Intel超线程(架构性旁路 architectural side channel),WEP, WPA, GSM(各种错误…)
传统智慧:不要自己写加密代码!
· 传输的时候用SSL
· 保护数据用GPG
· “如果你在代码里写了A-E-S几个字母,那么你错了。” ---Thomas Ptacek
事实:不管我怎么说,你肯定会自己写加密代码的,你最好明白自己在做什么。
事实:大部分应用只需要一小部分好的标准加密方法,很容易做对。
在接下来的55分钟之后你应该能:
· 99%的情况里你都知道该做什么
· 知道最常见的错误是哪些
· 如果你需要做一些非标准的事情,你真的最好咨询一下密码学专家
密码学可以抵御一些攻击,但不是全部。
· 三个"B":Bribery(贿赂),Burglary(盗窃),Blackmail(敲诈)
· 第四个"B": (Guantanamo) Bay (关塔那摩)
攻击人总是比攻击数据更昂贵。
攻击人总是比攻击数据更冒风险。
· 数据不会召开新闻发布会控诉它们遭受的虐待。
密码学的意义就在于它迫使美国政府来拷打你。
· 希望他们认为你的数据没有那么重要。
密码学有三个目的:加密(Encryption),认证(Authentication),身份识别(Identification)。
· 加密能阻止坏人读取你的数据
· 认证(也叫签名Signing)阻止坏人偷偷修改你的数据
· 身份识别阻止坏人伪装成你
有时候认证和身份识别在一个步骤里完成:“这段信息在我写完之后没有被修改过”,以及“我是Colin”,被一句话代替“这段信息在Colin写完之后没有被修改过”。
大部分时候你会想把2个或者更多加密组件组合在一起。
【密码学语言】
明文是我们在乎的数据。
密文是坏人看到的数据。
密钥用来对上述两种状态进行转换,有时我们需要多个密钥。
对称加密是指从明文转为密文、从密文转为明文时,使用同一个密钥。
非对称加密是指两个方向的转换不使用同一个密钥。
理想的加密组件是不存在的,但如果一个加密组件不是很理想,那它一般被视为不能使用。
【哈希】
一个理想的哈希函数H(x)可以将任意长度的输入映射到n比特的输出,而且是:
· 防冲突
· 不可逆的
防冲突是指需要花费大约2^(n/2)的时间来找到两个有相同哈希值的输入。
不可逆是指给定一个哈希值,需要约2^n的时间来找到一个产生此值的输入。
别的方面就无法保证什么了。
· 如果知道了H(x),攻击者可能可以算出一些输入的哈希值
应做:使用SHA-256
应做:在接下来5-10年,考虑切换到SHA-3
应做:如果你可以安全的分发一个哈希函数H(x),而且希望验证你通过不安全渠道得到的x'实际上与x相等,用哈希函数来做。
不要做:使用MD2, MD4, MD5, SHA-1, RIPEMD
不要做:把FreeBSD-8.0-RELEASE-amd64-disc1.iso和CHECKSUM.SHA256放在同一个FTP服务器上,还觉得自己做了一件有用的事情
不要做:拿一个哈希函数作对称式签名
【对称认证】
对称认证通过提供一个信息证实代码(message authenticatio code, MAC)来实现。
理想的信息证实代码fk(x)(k为下标)使用一个密钥将任意长度的输入映射到n比特输出,这使得攻击者即使获得了(x, fk(x)),也需要2^n的时间来生成(y, fk(y))
· 有时被称为“随机函数”
与哈希函数不同,即使你知道了fk(x),对于其他的y也无法算出fk(y)
· Flickr API就使用了哈希来校验API请求,实际上他们应该用MAC的
应做:使用HMAC-SHA256
应做:确保HMAC-SHA256的输入不包含生成相同数据的不同消息
· 亚马逊和Flickr都做错了
避免:CBC-MAC
· 理论上安全,但是会把加密块暴露给攻击者
避免:Ploy1305
· 如果你名叫Daniel Bernstein,那你可以继续用。否则你永远无法做出安全而且正确的实现。
不要做:当你验证一个签名时,通过计时旁路(timing side channels)泄露信息
【旁路攻击】
所谓旁路就是除了密文以外,攻击者能够获取的其他信息
· 加密系统是通过数学设计来定义的,而旁路是随着加密系统的具体实现而自然产生的
最常见的旁路就是计时旁路:加密、解密、签名、验证各步骤都花了多长时间。
其他旁路包括电磁泄露,电力消耗,微观架构特性(比如有超线程功能的Intel CPU的L1数据缓存逐出(eviction))
应做:当你打算把加密实体(比如智能卡)的访问权赋予坏人时,记得先咨询密码学专家
应做:当你打算允许坏人在你用来加密的机器(比如虚拟系统)上运行代码时,先咨询密码学专家
应做:当你打算发布一款会用各种又新颖又激动人心的方式泄露信息的CPU时,记得先咨询密码学专家
· Intel可能就做错了
不要做:写一段会通过它的运行时间来泄露信息的代码
【计时攻击】
避免:对表格进行依赖密钥或依赖明文的查询
不要做:依赖于密钥或铭文的程序分支(if, for, while, foo ? bar : baz)
想都不要想:写下这样的代码
for (i = 0; i < MACLEN; i++)
if (MAC computed[i] != MAC received[i])
return (MAC IS BAD);
return (MAC IS GOOD);
if (MAC computed[i] != MAC received[i])
return (MAC IS BAD);
return (MAC IS GOOD);
应做:写这样的代码
for (x = i = 0; i < MACLEN; i++)
x |= MAC computed[i] − MAC received[i];
x |= MAC computed[i] − MAC received[i];
return (x ? MAC IS BAD : MAC IS GOOD);
· Goolge Keyczar在这里犯了错
【分组加密(blcok cipher)】
对称加密通常是用分组加密实现的。
理想的分组加密用一个密钥将n比特输入一一映射到n比特输出,记为Ek(x)(k为下标),从而使得对于任意的(x', k')≠(x, k),知道数对(x, Ek(x))后猜出(x', Ek'(x'))的几率不超过2^-n。
· 有时被称为随机置换(random permutation)
我们一般关注的是对于x'≠x,Ek(x)不会泄露关于Ek(x')的信息
· 如果一个攻击者可以通过观察分组加密处理不同的密钥的方式来得到有用的信息,那么这个分组加密就是容易遭到相关密钥攻击(related-key attack)的。
应做:使用AES-256
· AES容易遭到相关密钥攻击,但只要你把其他方面处理好,这无关紧要。
· 理论上说AES-128已经足够强了,但是分组加密很容易产生旁路,更长的密钥有助于增强加密,即便部分密钥暴露。
不要做:使用blowfish
想都不要想:使用DES
避免:Triple-DES
不要做:单独使用分组加密;应该将其放在一系列操作模式里面
【分组加密操作模式】
一个分组加密操作模式告诉你怎样使用分组加密来保护数据流。
很多情况下,明文需要被填充,分成多个单位长度的块;分组加密操作模式会告诉你怎样做。
这些模式的名字都很古怪:ECB, CBC,CFB, OFB, CTR, IAPM, CCM, EAX, GCM...
· 别问我它们全称都是啥
大部分模式都只提供加密;有一些还提供认证
应做:使用CTR模式
不要做:使用既提供加密又提供认证的模式
想都不要想:使用ECB模式
应做:使用一个MAC(比如HMAC-SHA256)来验证你的加密数据
· 如果你觉得不需要这么做,咨询一下密码学专家。他会说“你错了”。
应做:在解密数据前对密文进行验证
【非对称认证】(Asymmetric authentication)
非对称认证使用一个签名密钥(signing key)将明文转换为密文,使用一个验证密钥(verification key)将密文转换为明文或“无效签名”(invalid signature)
· 使用验证密钥无法计算出签名密钥,但验证密钥通常可以通过签名密钥算出
· 密文通常由明文加签名组成
如果取得验证密钥的攻击者可以创建出任何合法的密文,或者能够欺骗你给任何明文签名,这种非对称加密方式将被视为被破解的。
应做:使用RSASSA-PSS(RSA signing with Probabilistic
Signature Scheme padding)
应做:使用2048位的RSA密钥,公共指数为65537,以及SHA256
不要做:使用 PKCS v1.5 填充
想都不要想:使用RSA不带填充(padding)
或许应当避免:DSA
或许应当避免:椭圆曲线签名方案
想都不要想:认证和加密使用同一个RSA密钥
【非对称加密】
与非对称签名一样,非对称加密是指使用公钥将明文转换为密文,使用私钥将密文转换为明文。
如果攻击者可以将给定的密文进行解密,即使他可以哄骗你解密任意其他密文,这种非对称加密方案将被视为已破解的。
大部分非对称加密方案对可加密的消息长度有较强限制。
应做:使用RSAES-OAEP (RSA encryption with Optimal
Asymmetric Encryption Padding)
应做:使用2048位的RSA密钥,公共指数为65537,SHA256和MGF1-SHA256
不要做:使用PKCS v1.5 padding
不要做:使用RSA不加填充
应做:生成一个随机密钥,然后对消息进行对称式加密,然后对对称式加密密钥进行非对称式加密。
应做:对RSAES-OAEP应非常小心,避免时间旁路攻击
【密码】(passwords/passphrases)
密码经常被直接用来验证身份,但也可以用来加密或认证。
应做:任何情况下都应避免使用密码
应做:尽快使用密钥生成函数将密码转换为密钥
· 如果你想和业界潮流接轨,使用PBKDF2
· 如果你想有2^8那么多倍的安全性,使用scrypt
想都不要想:在服务器上存储用户的密码
· 不要存,哪怕密码加了密
SSL是一个糟糕的系统
· SSL过于复杂,以至于没法安全的实现
· SSL可以攻击的地方太多,攻击者有充裕的选择
· SSL需要你决定相信哪一家证书签发机构
· 你想选择相信中国政府吗?
不幸的是,SSL往往是唯一的选择
应做:对于C-S架构的软件,将非对称签名验证密钥发布到客户端,然后以此为基础建立密码系统
应做:使用SSL来增强网站、email以及其他公共标准网络服务的安全性
应做:审慎选择证书签发机构
【奇怪的东西】
应做:向密码学专家进行咨询,如果:
· 如果攻击者能够物理接触到你的硬件(比如智能卡)
· 你需要尽量节约能源(比如智能手机)
· 你需要处理尽可能大的数据流(比如10 Gbps IPSec 隧道)
· 你需要传输尽量少的比特位数(比如与核潜艇进行通讯)
· 你想忽略我在这次演讲里提出的任何一条建议