C++,python,热爱算法和机器学习
全部博文(1214)
分类:
2011-04-10 20:31:59
然而,非对称加密算法的加密速度普遍较慢。我这里下了个 600M 的 Debian ISO,使用上篇文章讲的 gpg 加密方式进行非对称加密:
real 1m18.766s
user 1m10.816s
sys 0m2.302s
可以看到,耗时 1m18s,像现在的男同学下个片子动辄上 G 的,显然是等不及的。当然,非对称的加密强度要远远的高于对称的强度。
所以在实际应用中,往往不直接对文件进行非对称加密。我们使用对称加密来加密数据,再使用非对称加密来加密公钥。过程像下面这样:
jasey 生成一个对称密钥;使用该密钥来加密要传送的数据 A;用 kiki 给他的公钥来加密对称密钥;将加密后的消息跟加密后的密钥一起传送给 kiki。使用对称密钥加密后的信息跟非对称密钥加密后的密钥称又称为数字信封(很形象吧)。
而 kiki 收到 jasey 传给他的加密消息和加密密钥后,先用她的私钥解开加密的对称密钥,再使用解密后的对称密钥解开密文。
数字签名说到底还是以公钥密码体系为核心的一套技术。既然是非对称的,就会有加密速度普遍较慢的问题。这里先引入一个概念:Hash。
Hash(哈希,散列),通俗的讲就是将不论包含多少信息的文件最终变成一个固定长度文件的算法。这个 hash 有什么特点,请猛击这里。正是因为上述的这些特点,使他可以用来比较两个文件的异同:哈希值相同,原文件一定相同;哈希值不同,原文件一定不同(通常情况下)。
常见的 Hash 函数有 MD5,SHA1。留心的同学可能已经发现了,我上段话中在括号里面加了个“通常情况下”,但是万一异常了?我们看下面这段 wiki 上的话:
MD5(Message-Digest Algorithm 5),是计算机广泛使用的哈希算法之一。
MD5 较老,散列长度通常为 128 位元。2004 年,王小云证明 MD5 数字签名算法可以产生碰撞。什么是碰撞了?简单理解起来就是输入两个不同值,经过 MD5 出来后得到的最终结果确是相同的。2008 年,科研人员通过 MD5 碰撞成功生成了伪造的 SSL 证书,这使得在 https 协议中服务器可以伪造一些根 CA 的签名!
显然,我们现在已经能找到这样的 X,Y, X != Y,但是 MD5(X) == MD5(Y) 了,也就是说发生了碰撞。
虽然已经证实了,但是 Hash 发生碰撞的机会十分的小,所以大家目前没有必要惊慌。
接下来我们就借助 Hash 和非对称加密来实现一次数字签名:jasey 将要发送的信息 A 做一个 Hash(摘要);接着用自己的私钥来加密这个摘要,即签名;将得到的签名跟原始消息发送给 kiki。kiki 收到后首先用 jasey 的公钥来解密,得到 jasey 产生的摘要;接着将原始的信息进行一次摘要;比较两次摘要的结果,若相同则表示该消息确实是由 jasey 发出的。这样就实现了身份的认证(防抵赖)以及消息的完整性(摘要)。
签名的应用场景很广,在现实的应用中,经常能看到这样的身影:很多开源软件的下载页面都会有 MD5 验证或者 gpg 的签名(上篇已经叙述了如何使用);通过 Email 广播时,先签名,防止卡他人假冒广播者;再如大家经常看到的 HTTPS,POP3s,网银证书等等(https 问题将在接下来的文章中涉及)。
上述的情况,其实已经不单单是一个简单的签名了,诸如 HTTPS 这样的协议是融合了加密的。
下面我们就描述一个比较完善的数据传输过程,先签名后加密(刚开始接触理解起来可能有点困难,没关系,多读几遍,自然就理解了):
jasey 将待发送的消息做摘要,用自己产生的私钥加密摘要做签名;使用对称密钥加密原始消息和签名得到消息密文;用 kiki 的公钥加密对称密钥;将加密后的对称密钥跟消息密文传送给 kiki。
kiki 收到后,首先用自己的私钥解密 jasey 生成的对称密钥;接着用对称密钥解密得到消息明文和数字签名;计算原始消息的摘要;用 jasey 的公钥解密签名;比较两份摘要。