Pulpcode

捕获,搅碎,拼接,吞咽

0%

从一次数字签名的学习中总结做技术的一些思路

情景

也许是你某次了解了一些关于数字签名的知识,想要系统的学习一下。或者是你的某个项目让你不得不找一种技术方案,你找到了数字签名,然后打算继续学着看看怎么用。

资料

首先你会读到类似的资料(来源于网络):

“发送报文时,发送方用一个哈希函数从报文文本中生成报文摘要,然后用自己的私人密钥对这个摘要进行加密,这个加密后的摘要将作为报文的数字签名和报文一起发送给接收方,接收方首先用与发送方一样的哈希函数从接收到的原始报文中计算出报文摘要,接着再用发送方的公用密钥来对报文附加的数字签名进行解密,如果这两个摘要相同、那么接收方就能确认该数字签名是发送方的。

数字签名有两种功效:一是能确定消息确实是由发送方签名并发出来的,因为别人假冒不了发送方的签名。二是数字签名能确定消息的完整性。因为数字签名的特点是它代表了文件的特征,文件如果发生改变,数字摘要的值也将发生变化。不同的文件将得到不同的数字摘要。 一次数字签名涉及到一个哈希函数、发送者的公钥、发送者的私钥。

制造混乱

对于那些已经理解数字签名的人而言,这段话再简单不过了,可是对于一个初学者而言,想要弄懂这些,可要大费脑经。

一词多用

编程技术中,一个东西能干很多事情,常常是带来混乱的原因,早在大二学习c语言的时候,我就思考过为什么指针这么难懂,其实如果你能区分“指向”,“指针变量”,求指针,解地址。分别是什么样的操作,那么你就不会被*&这些符号搞混,要知道,*符号既可以用来解指针,又可以用来定义指针。

类似于指针,这个加密解密的名词也有些太泛了。比如说加密,其实数字签名本身并没有加密,此处的加密并不是我们泛指的对数据进行加密,这样数据就不能被人看见了。这里的“用私钥加密”,其实说成“用私钥进行签名”更合适。当然有人就是喜欢将签名也当成一种加密,这自然会制造混乱,提升门槛。

类似还有 “签名”,“哈希”,“摘要”,“指纹”。这些名词也会被混用,多用。增加理解难度。

一技多用

就拿哈希算法来说吧(比如md5,sha1),哈希算法带来的好处,就是不可逆性和唯一性。和它的相关使用都是围绕这两个属性。

但其实事实比这要复杂的多,比如我们在存密码的时候,不存密码存哈希,而且存的是加盐的哈希。然后许多人就能联想到我们数字签名也会用到加料哈希。而实际上数字签名的哈希只不过是为了使签名数据变短而已。

许多数学思想能够在多种地方使用,也在不经意间制造混乱,这就是联想带来的坏处,它让我们错误的理解模型。

问答

一段定义不足够让你完全理解一个模型,这个时候,我们需要提问,建立一些假设,填补大脑中的空白。

数字签名加密数据么?

不加密,实际上,签名和原数据一起以明文的方式被发送,抓包是完全可以抓到的,数字签名的目的,就是保证数字是正确的地方发来的,且没有被人修改。

数字签名为什么不顺便加密?

这是大多数学技术的人一个很不好的思维习惯,实际上技术本身是很理性的,每一个技术有它固定的用途和意义,加密有加密本身的方法和所解决的问题。不要做无用功,不要只感动自己。

这里的被人修改,是如何修改的?

很简单,明文传输,所以原始数据很容易被修改,再发送出去。

等等,如果我有公钥,那么我解开数据,修改数据,再重新生成签名不就行了?

但是你无法用私钥把数据加密再发送出去。

hash的意义何在,我直接将整个数据用私钥加密不就行了?既证明此数据是我发送的,又证明了它没有被修改。

理论上是可以的,但是你没有考虑到私钥签名会非常耗时耗空间。如果要私钥签名一个文件更是费时,传输也是问题,这个时候hash后再签名是最好的选择,因为hash可以保证唯一性,不可逆性。

hash的时候需要加料后哈希么?

不用,加料不是用在这里的,加料其实是用在一种类似哈希签名的算法。如果加料,难倒你要把加料算法像公钥一样告诉每一个人?

摘自支付宝文档:

当拿到请求时的待签名字符串后,需要把私钥直接拼接到待签名字符串后面,形成 新的字符串,利用 MD5 的签名函数对这个新的字符串进行签名运算,从而得到 32 位签名结果字符串(该字符串赋值于参数 sign)

其实这里将私钥当成只有你知我知的加料算法了。

如果想再次基础上加密怎么办?

请参考“数字信封”

总结

  1. 理清思路,消除混乱。

  2. 提出假设,填补漏洞。

  3. 建立正确的模型。

这就是我对学习此类技术问题的方法和总结。