哈希算法又称为哈希函数、散列算法、散列函数,它能从任何数据长度生成一个固定长度的消息摘要(如下图)。对于某个特定的消息而言,这个消息摘要(或哈希值)可以看做是这个消息的指纹,且该消息是唯一表示。哈希函数是数字签名和验证的核心部分。
哈希碰撞也就是说存在不同的消息(输入),使得哈希函数的输出,也就是散列值一样,这种概率非常非常低。以下面的md5为例,两个输入有细微差别,但是哈希值是一样的:
# coding: utf-8
import hashlib
# 两段HEX字节串,注意它们有细微差别
a = bytearray.fromhex("0e306561559aa787d00bc6f70bbdfe3404cf03659e704f8534c00ffb659c4c8740cc942feb2da115a3f4155cbb8607497386656d7d1f34a42059d78f5a8dd1ef")
b = bytearray.fromhex("0e306561559aa787d00bc6f70bbdfe3404cf03659e744f8534c00ffb659c4c8740cc942feb2da115a3f415dcbb8607497386656d7d1f34a42059d78f5a8dd1ef")
# 输出MD5,它们的结果一致
print(hashlib.md5(a).hexdigest())
print(hashlib.md5(b).hexdigest())
### a和b输出结果都为:
cee9a457e790cf20d4bdaa6d69f01e41
cee9a457e790cf20d4bdaa6d69f01e41
以CRC32为例,它的摘要长度为32bit,也就是说存在232种可能。如今互联网页面总数在2008年的时候就已经超过1万亿,如果采用CRC32的摘要,那么发生哈希碰撞的就很多。而MD5的摘要长度为128bit,也就是有2128种可能,但是目前已经证明MD5算法是不安全的。同样的SHA1算法(160bit)也被证明是不安全的,推荐使用SHA256算法才比较安全。
目前比较流行的哈希算法有MD5、SHA-1和SHA-2
总结来说,MD5和SHA-1已经不够安全,推荐至少使用SHA-256算法。
哈希算法的应用主要体现在以下3个方面:
非对称加密算法也称为公钥加密算法,其分为3个部分,分别是:公钥、私钥和加密解密算法。
非对称加密往往需要密码学安全伪随机数生成器来产生一对秘钥(公钥和私钥),这两者是成对的,公钥是可以公开的,而私钥则是用户自己保留。用私钥加密的数据只有公钥才可以解密(反过来,用公钥加密的数据,只有私钥可以解密)。公钥和私钥之间的这种数学关系,使得私钥可以用于生成特定消息的签名。而这个签名可以在不暴露私钥的前提下通过公钥进行验证。
也就是说我对一段消息用私钥进行签名(也就是加密),然后把这个数据连同签名和我的公钥发送给对方,对方就可以通过公钥对签名进行验证(解密)对比数据从而验证数据的有效性。
在比特币系统中,公钥生成的钱包地址用于接收比特币,而私钥则用于比特币支付时的交易签名。
在支付比特币时,比特币的所有者需要在交易中提交自己的公钥和该交易的签名。而比特币网络中所有节点可以通过所提交的公钥和签名进行验证,从而确认支付者对交易的比特币的所有权。
加密过程:通过加密算法和公钥对明文进行加密,得到密文
解密过程:通过解密算法(这里加密、解密算法要一样)和秘钥进行解密,得到明文。
如下图所示,加密过程是单向的,公钥加密后的密文只能用对应的私钥解密。
其中使用最广泛的是RSA算法(由发明者Rivest、Shmir和Adleman姓氏首字母缩写而来)是著名的公开秘钥加密算法,ElGamal是另一种常用的非对称加密算法。
非对称加密算法的应用非常广泛,下面列举常见的几种
生成密钥对
def create_genisus_keypair():
# 第一个节点的密钥对
pubkey, privkey = rsa.newkeys(1024)
with open('genisus_public.pem', 'w+') as f:
f.write(pubkey.save_pkcs1().decode())
with open('genisus_private.pem', 'w+') as f:
f.write(privkey.save_pkcs1().decode())
直接打开genisus_public.pem和genisus_private.pem,我们可以看到一长串的字符串。
genisus_public.pem:
-----BEGIN RSA PUBLIC KEY-----
MIGJAoGBAJIiGuUOlhKFQEHIr5YXa9uajM+sI5FEZ/8RJdR5EOC4Wo+9bZfyrvnu
PRBtK7PJzUXHdXCaNohPzA5IuiEpkoELPyWfCozQF9FAgK2Gyf1rBeC7e2lUvuwI
h5IXhRjC2Rom6wiJRWXn/W0/EezrXl8YlYmrRR1Boa9OB1RFJvJXAgMBAAE=
-----END RSA PUBLIC KEY-----
genisus_private.pem:
-----BEGIN RSA PRIVATE KEY-----
MIICYAIBAAKBgQCSIhrlDpYShUBByK+WF2vbmozPrCORRGf/ESXUeRDguFqPvW2X
8q757j0QbSuzyc1Fx3VwmjaIT8wOSLohKZKBCz8lnwqM0BfRQICthsn9awXgu3tp
VL7sCIeSF4UYwtkaJusIiUVl5/1tPxHs615fGJWJq0UdQaGvTgdURSbyVwIDAQAB
AoGAOiw7ep3A3iSPfOCQDXbLaANxNKa5DfYmVCKWZavALUUWQAxPmWJxh2rwgh6D
fDHEdpe9R5MMTF0/xRvsQGQvZU2sNNhA2ebVOB4mMCPcURYWCbJXjT14IC7rfwPp
YnkpiCHxP+HBS2xjMyf63vk7tKR/zCfzm9tsDAKqKuFUYPECRQCrQpiuYxp2Znch
szwR15q0HUpU8/HdCQlKdBK2fa4M2Y1xPqNjpOlQ2B8zCS3aOQ/9nhbVaRy0LqFD
sUjPPJsTqbaSyQI9ANpwsv1MHkpYGlYSrCItFS1oRoD/foxByVdVORCtarA0z9xe
Am8kEi9HcnZf2jsYvqHAeQsTtuPw0PvMHwJEXL0+csilztHj1zL452yKkNh/pQtI
wPogttmuPHZIZxrz9gwGbHIkCixOkNN6qf5Wg281TDGUYpoRp9d75wUZsQcpH8kC
PE0rvYBREO5w27UG2bslNDMbgLT4DkwcvbXVzNhAe82OitSufauoEaiUVDLPwDha
kJZyehDYwSccH6ilPwJFAIhBzCQ61A2zfEJlgKeuX3OJGq1pywpnv+vFyqnDc4T6
oEW9kfnrAI+6x4L4jyyHOWMNfkAPajtkQ+YwxZqUmKL8ixr0
-----END RSA PRIVATE KEY-----
加密、解密
# 导入密钥
with open('genisus_private.pem', 'r') as f:
privkey = rsa.PrivateKey.load_pkcs1(f.read().encode())
with open('genisus_public.pem', 'r') as f:
pubkey = rsa.PublicKey.load_pkcs1(f.read().encode())
# 明文
message = 'hello world'
# 公钥加密
crypto = rsa.encrypt(message.encode(), pubkey)
# 私钥解密
message = rsa.decrypt(crypto, privkey).decode()
print(message)
数字签名,就是只有信息的发送者才能产生的别人无法伪造的一段数字串,这段数字串同时也是对信息的发送者发送信息真实性的一个有效证明。它是进行身份鉴别和网上安全交易的通用技术。
数字签名应用了前2节所说到的非对称加密技术(公钥加密算法)和哈希算法。
数字签名技术的应用很广泛,例如个人安全邮件证书、访问安全https站点、网上签约、电子交易等。
首先生成一对秘钥(公钥和私钥)
# 明文
message = 'hello world'
# 导入密钥
with open('genisus_private.pem', 'r') as f:
privkey = rsa.PrivateKey.load_pkcs1(f.read().encode())
with open('genisus_public.pem', 'r') as f:
pubkey = rsa.PublicKey.load_pkcs1(f.read().encode())
# 私钥签名
signature = rsa.sign(message.encode(), privkey, 'SHA-1')
# 公钥验证
try:
rsa.verify(message.encode(), signature, pubkey)
except rsa.pkcs1.VerificationError:
print 'invalid'
关注我的微信公众号(shuwoom的博客),每周定期推送文章:
我写的相关文章:
[1] 《区块链快速入门》
[2] 《比特币交易原理分析》