对称密码(对称秘钥加密)
在对称密码体系中,相同的密码用来加密(encrypt)和解密(decrypt)报文,因此无论对发送者还是接受者,他们都知道秘钥。加密和解密的过程如下图所示
M-明文,即原始报文
K-秘钥
C-密文
E-加密函数
D-解密函数
对称密码可以分为两种:分组密码和序列密码
哈希加密
哈希加密是独立与对称密码和对称加密体系的,因为它不需要解密。密码学上的哈希函数有下面几个特征:
1.输入可以是任意长度
2.输出是固定长度
3.给出任意的输入(报文)可以很容易的计算出哈希值H(x)
4.哈希函数是不可逆的,即给定,不能根据Y推算得到x
5.不存在碰撞,即不存在,使
哈希函数算法
MD4
MD4(RFC 1320)是 MIT 的Ronald L. Rivest在 1990 年设计的,MD 是 Message Digest 的缩写。它适用在32位字长的处理器上用高速软件实现–它是基于 32位操作数的位操作来实现的。
MD5
MD5(RFC 1321)是 Rivest 于1991年对MD4的改进版本。它对输入仍以512位分组,其输出是4个32位字的级联,与 MD4 相同。MD5比MD4来得复杂,并且速度较之要慢一点,但更安全,在抗分析和抗差分方面表现更好
>>import hashlib
>>hashlib.md5('这是一段报文'.encode('utf8')).hexdigest()
'fff9cb83fd8a96f71f87e25441d67087'
>>hashlib.md5().hexdigest()
'd41d8cd98f00b204e9800998ecf8427e'
SHA-1
1995年发布,SHA1是由NIST NSA设计为同DSA一起使用的,它对长度小于2^64位的输入,产生长度为160bit的散列值,因此抗穷举(brute-force)性更好。SHA-1 设计时基于和MD4相同原理,并且模仿了该算法。
SHA-1在许多安全协议中广为使用,包括TLS和SSL、PGP、SSH、S/MIME和IPsec,曾被视为是MD5(更早之前被广为使用的散列函数)的后继者。但SHA-1的安全性在2000年以后已经不被大多数的加密场景所接受。2017年荷兰密码学研究小组CWI和Google正式宣布攻破了SHA-1
>>import hashlib
>>hashlib.sha1('这是一段报文'.encode('utf8')).hexdigest()
'1c28ec6278a42f81e853a170ef808566a541ec81'
>>hashlib.sha1(b'\xe8\xbf\x99\xe6\x98\xaf\xe4\xb8\x80\xe6\xae\xb5\xe6\x8a\xa5\xe6\x96\x87').hexdigest()
'1c28ec6278a42f81e853a170ef808566a541ec81'
SHA-2
2001年发布,包括SHA-224、SHA-256、SHA-384、SHA-512、SHA-512/224、SHA-512/256。虽然至今尚未出现对SHA-2有效的攻击,它的算法跟SHA-1基本上仍然相似;因此有些人开始发展其他替代的散列算法。
>>import hashlib
>>hashlib.sha256('我是报文'.encode()).hexdigest()
'62b6cd47e997023f6da68a1eb7bc041200dc6759dd1e593bb1438d1eabda23e1'
SHA-3
2015年正式发布,SHA-3并不是要取代SHA-2,因为SHA-2当前并没有出现明显的弱点。由于对MD5出现成功的破解,以及对SHA-0和SHA-1出现理论上破解的方法,NIST感觉需要一个与之前算法不同的,可替换的加密散列算法,也就是现在的SHA-3。
使用场景
文件校验
MD5 Hash算法的”数字指纹”特性,使它成为目前应用最广泛的一种文件完整性校验和(Checksum)算法
数字签名
由于非对称算法的运算速度较慢,所以在数字签名协议中,单向散列函数扮演了一个重要的角色。对 Hash 值,又称”数字摘要”进行数字签名,在统计上可以认为与对文件本身进行数字签名是等效的。而且这样的协议还有其他的优点。
非对称密码(非对称秘钥加密)
在对称加密的体系中,加密和解密使用同一个秘钥,如果在秘钥分发的过程中秘钥被盗取,加密就形同虚设。而且秘钥的管理也非常繁琐,如果要n个人要互相交流,每个人必须保存n-1份秘钥,如图
在非对称加密体系中,加密者拥有私钥,接受者拥有公钥,加密者使用私钥将报文加密成密文传递给接受者,接受者直接使用公钥就可以解密密文,不存在秘钥传递的问题。
RSA加密算法
签名算法
我们有一份文件可以计算出他的Hash值,一旦文件被篡改做产生的Hash值也将变化,Hash函数解决了完整性的问题,然而并没有解决认证的问题,如果攻击者不但把文件给篡改了还把hash值给改了,这样接收者就察觉不到文件已经出了问题。
我们需要一种签名机制,这种签名机制能保证所有人都能对文件的完整性进行认证,同时又能验证这份文件确实是发送者发的,攻击者无法伪造这个签名。
设计原则
数字签名常常和哈希函数在一起使用,给定一段明文M,我们可以计算出明文的哈希值h(M),然后将哈希值进行某种加密S后,附在明文上,结构如下:
在上述结构主要依赖于哈希值不存在对撞,即不同的明文之间不会存在相同的哈希值,实际上每种公钥加密体系都能实现,主要有3种签名算法: Schnorr签名,Digital Signature Algorithm(数字证书签名),RSA签名
DSA签名
原理如下
1.选择一个1024位的素数p,此时有一个群组
2.选择另一个160位的素数q,q除以p-1和q都在群组中,并且群组属于
3.其中要到的哈希算法是SHA-1
秘钥生成:
1.选择p和q,条件就是上面所表达的,换成数学的表达方式就是并且z属于群组
2.选择一个g,使下面的公式成立, 并且
3.在范围1,…..q−1的选择一个随机数x
4.计算出来
5.其中公钥就是,私钥就是
签名过程:
1.在范围1,…..q−1的选择一个随机数r
2.计算出来
3.计算出
4.将签名结果(s,t)附属在消息上。
验签过程:
1.计算出
2.计算出
3.计算签名
4.比较是否与s相同
RSA签名
秘钥生成
1.选择两个大素数,p和q
2.计算出他们的欧拉函数,
3.我们选择一个整数e>1,并使即e要和欧拉函数(非公约的个数),互为素数。
4.我们使,根据欧几里得拓展定理计算出d.
5.然后我们就得到了公钥,然后对外发布公钥
6.私钥就是
签名过程:
我们假设需要加密的信息为M,其中M在1,,,,n−1这个范围内,h为哈希加密函数,则签名的过程如下:
验签过程:
计算出明文的哈希值h(M),比较h(M)是否和相应,如果相同则验签成功。
其他
Base64
Base64是一种用64个字符来表示任意二进制数据的方法。Base64的原理非常简单,对二进制数据进行处理,每3个字节一组,一共是3x8=24bit,划为4组,每组正好6个bit:
这样我们得到4个数字作为索引,然后查表,获得相应的4个字符,就是编码后的字符串。
所以,Base64编码会把3字节的二进制数据编码为4字节的文本数据,长度增加33%,好处是编码后的文本数据可以在邮件正文、网页等直接显示。
如果要编码的二进制数据不是3的倍数,最后会剩下1个或2个字节怎么办?Base64用\x00字节在末尾补足后,再在编码的末尾加上1个或2个=号,表示补了多少字节,解码的时候,会自动去掉。
>>import base64
>>base64.b64encode(b'binary\x00string')
b'YmluYXJ5AHN0cmluZw==' # (13 + 2) / 3 *4 = 20
>>base64.b64decode(b'YmluYXJ5AHN0cmluZw==')
b'binary\x00string'
>>'我是报文'.encode('utf8')
b'\xe6\x88\x91\xe6\x98\xaf\xe6\x8a\xa5\xe6\x96\x87'
>>base64.b64encode('我是报文'.encode('utf8'))
b'5oiR5piv5oql5paH' # 12 / 3 * 4 = 16
>>str(base64.b64decode(b'5oiR5piv5oql5paH'), encoding='utf8')
'我是报文'
refer:
http://www.ehcoo.com/cryptology.html
http://www.ehcoo.com/cryptology1.html
https://www.liaoxuefeng.com/wiki/001374738125095c955c1e6d8bb493182103fac9270762a000/001399413803339f4bbda5c01fc479cbea98b1387390748000