椭圆曲线数字签名应用原理
Posted yyDrifter
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了椭圆曲线数字签名应用原理相关的知识,希望对你有一定的参考价值。
椭圆曲线数字签名应用原理
本文旨在理解椭圆曲线数字签名的过程,不涉及数学推导与过多专业术语。如想了解椭圆曲线数字签名的底层数学原理,请参考libsecp256k1比特币密码算法开源库(五)中公钥生成、签名和签名验证中的相关内容。
收发文件场景下的数字签名
在开始前定义几个量:文件的发送方A、文件的接收方B、企图窃密或篡改文件的第三方C。可以想象一个场景,某天B收到了一个文件,这个文件说是A发来的,但是B不知道这个文件是不是A发来的,如果是A发来的,B也不知道文件的内容是否被篡改过了。数字签名就可以给B解决这两个问题。
在回答这个问题前,先说B收到了A发来的文件。要保证这个文件不会被C知道是什么意思,首先需要对这个文件加密。
在非对称加密体系中,要用公钥加密私钥解密。
下面具体解释一下私钥和公钥:首先每个人都有自己的公钥和私钥对,就是说A有他的公钥a和私钥a,B也有他的公钥b和私钥b,私钥是在本地产生的,也就是说某天A想,他也许该有个私钥了,于是他就自己想了一串数当做自己的私钥a,这个私钥就他自己知道,不能告诉别人(不然就不是本地了),但是他的公钥会是什么样子呢,他也不知道,他将自己想出来的私钥a放到椭圆曲线方程中,生成了他的公钥a(私钥生成公钥的具体数学过程可以看我之前的博客,但这里不会影响理解)。这个公钥很复杂,A可以把他的私钥放到椭圆曲线里面得到他的公钥,但把他的公钥放到椭圆曲线里面却无论如何得不到他的私钥。A可以将他的公钥告诉任何人,当然也可以告诉给窃密者C。B产生公钥b和私钥b的过程也一样。
某天A想给B发消息了,于是A找到了B的公钥(前面说过公钥是完全公开的),A用B的公钥b对自己要发送的文件加密——这样C就完全不知道这个文件内容是什么了——然后将加密的结果发给了B,B得到这个文件后用自己的私钥b就可以对文件解密,看到文件的内容了。
这个过程当然存在一些问题,B解开这个文件一看开头一个Dear B结尾一个Yours A,文件看样子是A发来的,但有没有可能是C假冒A发给B的呢?如果是A发来的,那么文件的内容是否被偷偷篡改过了?解决这两个问题就需要数字签名。
那么数字签名是如何实现的呢,要用私钥签名公钥验证。
先说数字签名是怎么得来的:首先A会对自己要发送的文件进行hash运算,hash运算结果称之为这个文件的hash摘要。hash函数有几个性质:hash会让这个文件变成很短的一个比特串(具体多短要看使用的hash函数),即便是A给B发了一本莎士比亚歌剧最后hash得到的hash摘要也会是很短的比特串;用同一个hash函数哈希结果不同,但长度一定是一样的,用同一个hash函数对莎士比亚格局的hash结果和一个字母的hash结果是等长的比特串;根据hash摘要无论如何也无法推断或还原成为最初的源文件;hash具有雪崩的特点,即改变hash前的文件哪怕一个标点,得到的hash结果也会完全不同,同样如果源文件没有改变,hash结果也不会改变。hash结束得到文件的hash摘要,A的私钥a和A随机产生的随机数k(k究竟是什么参见我之前的博客,但这里不会影响理解)经过一系列运算会得到A的数字签名 sign a。
然后说加入数字签名后发送文件的过程:A会将他的数字签名sign a,他的公钥a附带上他的被B的公钥b加密的文件一起发送给B,B收到之后会先用自己的私钥b对文件进行解密,得到这个文件,再对收到的这个文件进行hash运算。然后B会用这个文件的hash摘要、A的公钥a来对这个数字签名sign a进行验证,如果验证通过了,就既说明这个文件在传输过程中没有被恶意篡改,又说明这个文件也确实是A发来的。
比特币区块链场景下的数字签名
在开始前定义几个量:一笔交易 β \\beta β的发起方P、交易的接收方A,即A收到了P转来的钱,随即A用从P得到的钱发起另一笔交易 α \\alpha α,交易 α \\alpha α的发起方A、交易的接收方B,即A把从P那里得到的钱转给了B。在本例中重点分析A向B转账的交易 α \\alpha α。
在正常生活中转账一般要通过银行机构,A给B转账时首先A会到银行去,提交要转账的信息,银行就会看A账户里面余额是不是够给B转账,如果够就把A账户中的相应金额转给B。
但在比特币区块链场景下,情况会有些不同。区块链是一个去中心化的系统,不存在“银行”的概念,A给B转账时,A有没有钱自然也不会由一个中心化的系统(即银行)来核验,而是由非常多的网络节点来核验。
这里我们直接假设网络中的节点大部分都是好节点,如果一个交易是正确的,好节点就会把这个正确的交易写入到自己的区块里,然后这个节点会通过“挖矿”让自己的区块成为一个合法区块,并告诉其他节点自己的合法区块,其他节点经过验证,发现这个区块里面的交易都是正确的,而且这个区块本身也是合法的,就会接纳这个区块。当这个区块真正被接纳后,这个交易也就不可被篡改,A给B转账这件事也就坐实了。在这个过程中就算有一些作恶的坏节点就是认为一个正确的交易是错误的,始终不把一个正确的交易给装到自己的区块里面,也会有大部分的好节点愿意把这个交易装到自己的区块里面。
那么节点们核验一个交易是不是正确的标准是什么呢?试想一个A与B交易的场景:某天B收到了来自A的一笔钱,那么这笔钱究竟是不是A本人同意转出的钱呢,毕竟也有可能是B偷用A的钱转给了自己;如果真的是A把这笔钱转给了B,B是否真的就得到这笔钱了,也就是说A可能没有钱,A给B转的钱就是一张“空头支票”。
所以,节点们核验一个交易是不是正确就看两点:第一,钱是A本人转给的B,不是有人偷用A的钱转给B;第二,A确实有钱可以转给B。
想要核验这两点,需要理解在一笔交易中有两个重要的概念,那就是输入和输出。在一笔交易中可能有多个输入,也可能会有多个输出。这其实很容易理解,一个人转给另一个人的钱可能来自很多个人,同时一个人也可能把一笔钱转给了很多个人。但这里为了方便理解,交易
β
\\beta
β只包含P给A转钱,对应的后续交易
α
\\alpha
α也只包含A给B转钱。交易
β
\\beta
β中有一对输入和输出,交易
α
\\alpha
α中也有一对输入和输出。
在交易
α
\\alpha
α的输入中,A给出了自己的数字签名sign a和公钥a,在交易
α
\\alpha
α的输出中,A给出了转账接收方B的公钥b的hash值,即
h
a
s
h
(
公
钥
b
)
hash(公钥b)
hash(公钥b);同样的,在交易
β
\\beta
β的输入中,P给出了自己的数字签名sign p和公钥p,在交易
β
\\beta
β的输出中,P给出了转账接收方A的公钥a的hash值。
这里我们只看A给B转账的交易
α
\\alpha
α,那么其实想要核验一个交易是不是正确就很简单了:第一,核验钱是不是真的由A转出,只需在交易
α
\\alpha
α的输入中,用A的公钥a验证数字签名sign a是否正确,如果验证正确,那么这笔钱确实是由A转出的;第二,核验A是否真的有钱转给B,只需将交易
α
\\alpha
α的输入中A的公钥a求hash值,与交易
β
\\beta
β的输出中的A的公钥a的hash值比对,如果一样,就说明A确实有一笔来自P的转账,也就说明A真的有钱转给B。
同样地,B也可以使用这样的方式将来自A的钱转给其他人。
以上是关于椭圆曲线数字签名应用原理的主要内容,如果未能解决你的问题,请参考以下文章