密码学是研究编制密码和破译密码的技术科学。
密码学的历史最早可以追溯到几千年以前,古今中外都有密码学运用的记载,从历史看,战争很大程度给密码学提供了应用环境,推动了密码学的发展,密码学按照发展历程,大体可以分为三个阶段,手工加密、机械加密和计算机加密阶段,下面是近代密码学的一些重要进展。
1949年,信息论始祖克劳德·艾尔伍德·香农(Claude Elwood Shannon)发表了《保密系统的通信理论》一文,把密码学建立在严格的数学基础之上,奠定理论基础,从此成为真正的科学。
1976年,密码学专家惠特菲尔德·迪菲(Bailey Whitfield Diffie)和马丁·赫尔曼(Martin Edward Hellman)两人发表了《密码学的新方向》一文,解决了密钥管理的难题,把密钥分为加密的公钥和解密的私钥,提出了密钥交换算法Diffie-Hellman。
1977年,美国国家标准技术研究所制定数据加密标准(Data Encryption Standard ),将其颁布为国家标准。
1977年,麻省理工学院的罗纳德·李维斯特(Ron Rivest)、阿迪·萨莫尔(Adi Shamir)和伦纳德·阿德曼(Leonard Adleman)一起提出RSA加密算法,RSA就是他们三人姓氏开头字母拼在一起组成的。
1997年4月,美国ANSI发起征集AES(advanced encryption standard)的活动,并为此成立了AES工作小组,经过几年的时间筛选,最终采用了由比利时的Joan Daemen和Vincent Rijmen设计的Rijndael算法,并在2002年5月26日成为有效的加密标准。
按密码体制划分:对称密码体制密码学和非对称密码体制密码学对应的有对称密码算法和非对称密码算法。
消息摘要算法又称散列算法,其核心在于散列函数的单向性,即通过散列函数可获得对应的散列值,但不可通过该散列值反推其原始信息,这是消息摘要算法的安全性的根本所在,我们通常使用该算法判断数据的完整性。
消息摘要算法我们常见比如MD(Message Digest)、SHA(Secure Hash Algorithm)、HMAC(Hash Message Authentication Code)等,常用于验证数据的完整性,是数字签名算法的核心算法。
我们以微信支付的接口调用分析一下摘要算法怎么应用的,首先可以打开微信支付如下相关文档:
微信支付统一下单接口文档
微信支付签名过程
对称加密简单的说就是加密和解密使用同一个密钥,解密算法是加密算法的逆运算。
对称加密算法主要有DES、DES算法的变种DESede、DES替代者AES算法、IDEA、PBE等
非对称加密算法称为双钥或公钥加密算法,跟对称加密算法不同的是,对称加密算法只一个密钥,非对称加密算法 一个公钥和一个私钥,一个用于加密,另外一个用于解密。
简单的说:一对密钥公钥A和私钥B,A加密只能B解密,B加密只能A解密。
非对称加密算法源于DH算法(Diffie-Hellman,密钥交换算法)由W.Diffie和 M.Hellman共同提出,该算法为非对称加密算法奠定了基础,下面我们先来了解下密钥交换算法DH和ECDH算法。
为什么需要密钥交换算法?前面我们提到对称加密算法加解密都是用同一个密钥,我们可以想一下,我们怎样能安全的把一个密钥给到对方呢?比如我们经常用到HTTPS,大家都说HTTPS加密了是安全的,那它加密的密钥怎么来的呢?很显然我们在访问一个https地址的时候,事先并没有密钥,访问过程中客户端跟服务端通过握手协议协商出来的密钥,如果服务端直接把密钥在网络上传输那肯定不安全的,所以这过程到底发生了什么?后面专门分析https的时候会详细写,这里先了解下该算法。
DH密钥交换算法的安全性基于有限域上的离散对数难题
ECDH密钥交换算法是基于椭圆曲线加密
从上面图中可以看出,DHECDH密钥交换算法交互双方都会向对方公开一部分信息,即所谓的公钥,这部分即使被别人拿到了也不会威胁到最终的密钥,这里很关键的一点是甲乙两方公布的公钥是不相同的,但是最终生成的密钥两边是一致的,这里是利用的算法原理,有兴趣的可以去查阅详细的算法公式,因为最终的密钥不需要传输给对方,所以很大程度保证安全性。
非对称加密算法:
比较典型的非对称加密算法有RSA、ECC、ElGamal,RSA算法基于大数因子分解难题,而ElGamal和ECC算法则是基于离散对数难题。
从上面消息传递模型我们可以看出,非对称加密算法遵循“私钥加密,公钥解密”和“公钥加密,私钥解密”的原则,但是有一点需要注意,公钥是公开的,所以用在什么场景是需要根据该算法的特征来考虑的,比如既然公钥是公开的,你用私钥加密敏感数据传递给第三方合适么?显然不合适,因为公钥公开的,别人都可以拿到公钥,也就意味着你加密的数据都可以解密,所以适合的场景比如私钥加密,公钥只是用来验证加密的内容,每个人都可以来验证,该场景是不在乎加密内容被其它攻击者看到的,甚至说内容本来就是公开的,对于接收者用公钥确保内容没有被篡改即可,所以我们通常说非对称算法“私钥签名,公钥验证签名”,另外一点,“公钥加密,私钥解密”,因为私钥只有我们自己手上有,所以理论上也只有我们自己可以解密,这样是安全的,https证书验证以及握手协议过程中会体现这一点。
数字签名算法可以看做是一种带有密钥的消息摘要算法,并且这种密钥包含了公钥和私钥。也就是说数字签名算法是非对称加密算法和消息摘要算法的结合体,遵循“私钥签名,公钥验证”的签名认证方式。
数字签名算法是公钥基础设施(Public Key Infrastructure,PKI)以及许多网络安全机制(SSL/TLS,VPN等)的基础。
数字签名算法要求能够验证数据完整性、认证数据来源,并起到抗否认的作用。
数字签名算法主要包括RSA、DSA、ECDSA共3种算法,其中RSA算法源于整数因子分解问题,DSA和ECDSA算法源于离散对数问题。
我们以蚂蚁金服开放平台上接口签名方案为例,详细说明可以打开如下文档:
蚂蚁开放平台签名专区
一、 恺撒密码
1.简单介绍
凯撒密码是古时候欧洲常用的一种加密方式:英文一共26个字母,它的加密方式是将这26个字母分别平移固定的位数,
假设位数=3,那么A=D,B=E,如下图:
如果想加密一个单词HELLO,根据上面的唯一对比,加密后的结果应该是LHOOR。颠倒字母后的顺序,使得常人无法读懂这些语句或者单词。如何解密呢,也很简单,只需要将收到的单词向前平移3个位置,就可以恢复到加密前的单词HELLO了。
2.破解
破解凯撒密码的方法很多,有一种暴力破解的方式,就是“遍历”。根据凯撒密码的加密方式,平移固定的位数,26个英文字母总共可以平移的方式是26种,假如位数n=26,其实相当于没有平移,A=A,循环了一次。
进行暴力破解:
n=1:LHOOR=KGNNQ
n=2:LHOOR=JFMMP
n=3:LHOOR=HELLO
这样就破解了,可以推算发位数n=3,其实就是秘钥=3,
最多尝试25次即可推算出加密的n值等于多少(当然这里只是讨论原理,不排除真实情况,可能凑巧某一个错误的n值解密出来的也是一个完整的单词或一段话的情况)。
二、 替换密码
1.简单介绍
替换密码和恺撒密码原理有些类似,个人感觉相当于恺撒密码的变种,替换密码增加了字母替换的随机性.
举个简单的例子,A=G,B=X,C=K
这里ABC..等26个字母都随机指向了“密码”本上的另一个随机的字母,这下就比较难反向推算出“秘钥”是多少了,数量级完全不一样。
简单的算一下可能存在的情况:
A=有25种表示方式BCD…
B=有除A以外24种方式表示CDE..
…
那么秘钥的存在情况是:
N=25!种方式,远远大于恺撒密码的26。
2.破解
面对25!数量级的加密方式,使用暴力破解的方式不再实用了,但是可以使用另一种方法,统计学
通过大量扫描英文书籍,可以得出如下结果(,这里只探究原理,并不追究这个统计的准确性):
26个字母在日常用语中的使用频率并不一样,比如字母E的使用频率遥遥领先,字母Z使用频率最低,这个相当于语言所残留在文字中的指纹,很难察觉但是真实存在。
根据这个原理,扫描“随机密码”文本,统计出各个字母的使用频率分布,找出使用频率最高的那个字母,极可能就是加密后的字母E。
3.随机加密还有很多变种,双重加密,擦掉“指纹”使得加密方式更进一步加固,不得不感叹古人的智慧,数学之美真奇妙。
别人用A的公钥加密传输的信息,只有A的私钥可以解密。保证了传输的信息的安全性。
A用A的私钥加密的信息,别人用A的公钥才可以解密。可以证明这个信息一定是A传输而来的。
共享秘钥(对称加密):速度快,但无法保证客户端与服务器之间传输时秘钥的安全性。
和公开密钥(非对称加密):安全,速度慢。
一、客户端请求SSL(安全套接层)通信,报文中包含自己支持的SSL版本、加密算法等。
二、服务器应答,附带自己的公钥证书,协商定好的SSL版本、加密组件。
三、客户端根据自己本地的收信任的CA公钥,解封服务器公钥证书,得到服务器公钥。客户端生成一个随机码序列,用服务器公钥加密后,发回服务器。
四、服务器用私钥解密后,再加密将字符串传回客户端。
五、客户端确认服务器身份后,生成对称加密算法和共享秘钥,使用服务器公钥加密后,传给服务器。
六、此后,双方使用对称加密算法加密数据,进行传输。
上面过程中,一二用于获得合法的服务器公钥,三四用于确认服务器是否为真正私钥持有者(因为,服务器公钥谁都可以得到)。
使用与明文比特序列一样长的,真正的随机数序列,进行加密,绝对安全,因为穷举破译后能得到整个秘钥空间,毫无意义。
以分组为单位进行处理的密码算法称为 分组密码。
采用 Feistel网络。
以 64 bit 为一个加密单位,首先分成两部分,各32 bit 。
加密过程持续数轮,每轮中,使用子秘钥与右侧数据经过轮函数生成一个序列,然后与左侧做 XOR 。
每轮结束后,左右两侧交换。
加解密结构相同,轮数任意,函数任意。
使用秘钥1、2、3对明文进行加密、解密、加密三个过程,称为三重DES。
解密过程是为了兼容老版DES,如果1、2、3秘钥相同,则成为了普通DES。
1、3秘钥相同,2不同时,称为DES-EDE2 。
1、2、3秘钥不同,称为DES-EDE3 。
采用的是 Rijndael 算法,SPN结构。
输入分组为 128bit(16字节),秘钥长度可以以 32bit 为单位,在128~256bit之间选择。
该算法由多轮构成,10~14轮。
一轮中:
SubBytes,按字节,将输入分开,以每个字节为索引,查表找值,替换。
ShiftRows(平移行),按字节,打乱上面的输出。
MixColumns (混合列),按4个字节,比特运算。
与轮秘钥进行 XOR 。
分组密码:每次处理,特定长度的一块数据。
流密码:对数据流,连续处理,需要保持内部状态,记录进度。
明文分组加密后,直接成为,密文分组。
特点:攻击者无需破译,即可操纵明文。
明文分组,与前一个密文分组XOR,加密得到自己的密文分组。
第一个分组的前一个密文分组,由 初始化向量(随机比特序列) 代替。
加密时,需要从头开始。因为需要与密文分组做 XOR 。
解密时,对密文分组解密,直接与密文分组 XOR 即可。
同样的明文分组,密文值可以不相等。
密文分组可以损坏,影响部分。
密文分组比特缺失,影响全部。
前一个密文分组,通过加密算法得到一个比特序列,称为 密钥流 。
明文分组,与密钥流 XOR,得到自己的密文分组。
解密时,加密算法对密文分组进行加密,得到密钥流,与密文 XOR 可得到明文。
重复攻击:假设秘钥相同。发送 4 个分组,攻击者保存了后面3个。转天,你又发送了 4 个分组,攻击者将你后面三个替换,接收方解密后,只有 2 号分组有错。
对于每个分组,初始化向量加密后,得到密钥流。明文与密钥流 XOR 后,得到密文。
速度快,密钥流可以提前生成,或者,生成秘钥过程可以和 XOR 运算并行。
对每个计数器加密得到密钥流。密钥流与明文分组 XOR ,得到密文分组。
计数器生成的数,由 一个随机序列 nonce + 从1开始的递增数字 组成。
对每个分组,计数器递增后,加密,得到密钥流。
能够以任意顺序处理分组,因为加密时需要的初始数字序列能够计算出来。
为了确保安全,有地理局限,与不同的人通信需要不同密钥,共享繁琐。
每个员工有自己的密钥,密钥分配中心使用个人密钥,包裹临时会话密钥,分配给各个员工使用。
密文=明文的E次方 MOD N
E 和 N 是RSA加密用的密钥,也就是说,E 和 N 的组合就是公钥。
明文=密文的D次方 MOD N
D 和 N 的组合就是私钥。
寻两个很大的质数 p 和 q,相乘得到 N
L为 p-1 和 q-1 的最小公倍数
随机数生成器,不停地生成数字,直到满足如下条件:
1 E L
E 和 L 的最大公约数为 1
根据 E ,计算 D
1 E L
E × D MOD L = 1
保证 E 与 L 互质,则 D 一定存在。
求对数很容易,求 离散对数 很困难
对一个大数字进行质因数分解,人类未找到高效算法
利用了 MOD N下,求离散对数的困难度
加密后,密文长度翻倍
利用了 MOD N下,求平方根的困难度
密码实现通过 对椭圆曲线上的特定点进行特殊乘法。
利用了该种乘法的逆运算非常困难这一特性
单向散列函数 又称为,消息摘要函数、哈希函数、杂凑函数
输入的消息 又称为,原像
散列值 又称为,消息摘要、指纹
完整性 又称为,一致性
根据任意消息,计算出的散列值长度,固定
用时短
消息不同,散列值不同
具备单向性
MD是消息摘要的意思
可以产生 128bit 的散列值,但它们的抗碰撞性已被攻破
SHA-1散列值长度为 160bit,强碰撞性已被攻破
其余的统称为 SHA-2,散列值长度为各自后面的数字
欧盟版本
第三代 SHA
消息上限 2^64 bit。
消息长度需要是 512bit 的整数倍。这样的 512比特 称为一个输入分组。
过程:
消息末尾添加 1
然后添加 0,直到最后一个分组的 448比特 的位置
最后 64比特 需要保存原是消息的长度
对每个分组计算 80 个 32bit 的值。
过程:
将 512bit 分成 32bit × 16组,称为 W0~W15
从15组中按规律取4组,进行 XOR 运算,结果循环左移 1 位,得到另外一组。如此反复,得到总共 80 组。
ABCDE 五个 32bit 的缓冲区,保存了 160bit 的消息内部状态。
内部状态与每个 512bit 的输入分组混合,一共 80 个步骤。
最终得到 160bit 的最终内部状态。
暴力破解:暴力寻找与 1亿元合同 散列值相同的文件
生日攻击:准备两份 散列值相同的 1亿元合同
可以辨别 篡改,无法辨别 伪装,因此还需要 认证技术
认证技术包括 消息验证码 和 数字签名
消息验证码:可以向通信对象保证消息不被篡改
数字签名:可以向任何人保证通信对象不被篡改
message authentication code,简称 MAC。
相当于 使用共享密钥的单向散列函数
SWIFT:负责银行间的交易,公钥密码使用前,都是人工配送密钥的。
IPsec:对IP协议增加安全性,采用的是消息认证码
SSL/TLS:网上购物等场景中所用协议。
过程:
密钥填充 至单向散列函数要求的输入分组大小
填充后的密钥 与 ipad(16进制的36不断循环)XOR,得到ipadkey
与 消息 组合,计算散列值
填充后的密钥 与 opad(16进制的5C不断循环)XOR,得到opadkey
与 上面得到的散列值 组合,计算新的散列值,为最终的MAC值
对第三方证明
防止否认
因为知晓密钥的只有两个当事人,第三者无法确定能拿到合法的密钥,无法自己计算合法MAC值
RSA:利用质因数分解难度的那个
ElGamal:利用求离散对数的困难度的那个,数字签名有漏洞,现仅用于公钥密码
DSA:Schnorr算法与ElGamal方式的变体,只能用于数字签名
Rabin:利用了求MOD N中平方根的困难度,可用于数字签名和公钥密码
例如,verisign公司的认证业务分为三个等级,等级越高,越严格
ITU 国际电信联盟和 ISO 国际标准化组织制定的 X.509 规范如下
大体包含以下内容:
签名前的证书——签名对象的各种消息
数字签名算法——签名时所用的算法
数字签名——得到的数字签名
PKI :为了能有效使用公钥而制定的一系列规范和规格
PKI 的组成要素如下
两种方法:一种是由认证机构生成,一种是由 PKI 用户自行生成
认证机构有一个 CRL(认证作废清单),具有数字签名,记载了已经作废的证书的编号。
认证时,从上(根证书)往下
对于密钥,关键的是 密钥空间的大小
DES 的密钥 实质长度(即,除去校验错误的比特后的长度)7字节
DES-EDE2 的实质长度 14字节,DES-EDE3 的实质长度 21字节
AES 的密钥长度可以从 128、192 和 256bit 当中选
会话密钥:每次通信中,仅使用一次的密钥
主密钥:一直被重复使用的密钥
CEK:Contents Encrypting Key
KEK: Key Encrypting Key
各个步骤中的密钥管理方法
两种方法:
用随机数生成密钥:使用具备不可预测性的伪随机数生成器生成随机数
用口令生成密钥:一般使用,口令 + 一串称为 salt 的随机数,得到他们的散列值作为密钥(这种方法称为:基于口令的密码)
事先共享
秘钥分配中心
使用公钥密钥
Diffie-Hellman 密钥交换
密钥更新:一种提高通信机密性的技术
原理:
使用 共享密钥 进行通信时,定期改变密钥。
双方使用同样的方法,对当前密钥求 散列值,并作为下一个密钥
优点:
后向安全:防止破译过去的内容
对密钥进行加密,然后保存
意义:
同时对多个密钥进行加密,可以减少保存密钥的数量
步骤:
P 为非常大的质数,G 为 P 的 生成元
目的为,将 随机数 A 的信息 含蓄地发给了 B
目的为,将 随机数 B 的信息 含蓄地发给了 A
计算方法:密钥 = (G ^ B MOD P) ^ A MOD P = G^(A × B) MOD P
计算方法:密钥 = (G ^ A MOD P) ^ B MOD P = G^(A × B) MOD P
对于一个质数 P ,只有它的生成元在进行 G ^ x MOD P 时,结果能够覆盖 0 ~ P-1 的所有数字
用途:用于安全的保存密钥
由来:
一 生成会话密钥 CEK ,加密消息
二 需要保密 会话密钥CEK,使用 密钥加密密钥KEK 对会话密钥进行保密
三 现在需要保密 KEK 这个密钥,选择使用口令生成这个 KEK
保密的问题最终都归结为了 安全保存密钥,然而我们记不住密钥。
于是,选择单向散列函数对口令生成散列值,作为密钥。
这个密钥无需保存,我们可以通过口令随时求得,口令也无法被反向推出,且口令方便记忆。
顺带,为了防止字典攻击,生成口令散列值时,需要使用 口令 + salt(随机数序列)
事先 已准备好 候选列表 的攻击方法
随机性
不可预测性
不可重见性
这三个性质,越往下越严格。分别称为:
弱伪随机数(不可用于密码学)
强伪随机数
真随机数
伪随机数生成器是公开的,种子是保密的。
确保种子的不可预测性,更加容易些。
种子是用来对伪随机数生成器的 内部状态进行初始化 的
R1 = (A × R0 + C) MOD M
数据有限,不能用于密码学
单向散列函数的单向性是支撑伪随机数序列不可预测性的基础
利用 AES 等对称密钥对内部状态进行加密
从当前时间开始,利用加密算法 求得加密后的时间的掩码 (因为密钥未知,别人无法推测出掩码信息)
与内部状态 XOR,加密后输出, 得到伪随机数序列
对伪随机数序列加密后,作为 下一个内部状态
针对极端情况的密码软件,具有全部功能。
TLS 由 TLS 记录协议 和 TLS 握手协议 叠加而成。
负责消息的 加密、压缩 和 认证
商定 客户端和服务器 所用的加密算法和密钥
负责 传递 变更密码的信号
发生错误时 通知对方
传输数据