主页 > 最新版官网imtoken > 数字签名
数字签名
数字签名
到目前为止交易区块哈希值如何生成,我们还没有深入了解“数字签名”的细节。在本节中,我们将探讨数字签名的工作原理以及如何在不泄露私钥的情况下提供私钥所有权证明。
椭圆曲线数字签名算法 (ECDSA)
以太坊中使用的数字签名算法是_椭圆曲线数字签名算法_,或_ECDSA_。 ECDSA 是一种基于椭圆曲线私钥/公钥对的数字签名算法,如 中所述。
数字签名在以太坊中有三种用途(见下面的侧边栏)。首先,签名证明私钥的拥有者,暗示以太坊账户的拥有者已经授权支付以太币或执行合约。第二,授权证明是_不可否认_。第三,签名证明交易数据在交易签署后没有也不能被任何人修改。
维基百科对“数字签名”的定义
数字签名是用于证明数字信息或文档真实性的数学方案。有效的数字签名使接收者有理由相信消息是由已知的发件人创建的(身份验证),发件人不能否认消息已发送(不可否认),并且消息在传输过程中没有被更改(完整性)。来源:
数字签名的工作原理
数字签名是由两部分组成的数学签名。第一部分是使用私钥(签名密钥)从消息(交易)创建签名的算法。第二部分是允许任何人仅使用消息和公钥来验证签名的算法。
创建数字签名
在 ECDSA 的以太坊实现中,被签名的“消息”是交易,或者更确切地说,是交易中 RLP 编码数据的 Keccak256 哈希。签名密钥是 EOA 的私钥。结果就是签名:
\(\(Sig = F_{sig}(F_{keccak256}(m), k)\)\)
地点:
有关 ECDSA 数学的更多详细信息,请参见。
函数 F**sig 产生一个签名 +Sig+,由两个值组成,通常称为 +R+ 和 +S+:
Sig = (R, S)
验证签名
要验证一个签名,必须有一个签名(R+和+S)、一个序列化的交易和一个公钥(对应于用于创建签名的私钥)。本质上,签名的验证意味着“只有生成此公钥的私钥的所有者才能在此交易中生成此签名。”
签名验证算法获取消息(交易的哈希值或其部分)、签名者的公钥和签名(+R+ 和 +S+ 值),如果签名对此消息有效且公开,则返回 TRUE键。
ECDSA 数学
如前所述,签名是由数学函数F**sig创建的,它生成一个由_R_和_S_两个值组成的签名。在本节中,我们将更详细地讨论函数 F**sig。
签名算法首先生成一个_ephemeral_(临时)私钥/公钥对。这个临时密钥对用于在涉及签名私钥和交易哈希的转换后计算_R_和_S_值。
临时密钥对由两个输入值生成:
1.一个随机数_q_用作临时私钥1.和椭圆曲线生成点_G_
从 _q_ 和 _G_ 开始,我们生成对应的临时公钥 _Q_(计算为 _Q = q * G_,与推导以太坊公钥的方法相同,请参阅)。数字签名的_R_值是临时公钥_Q_的x坐标。
算法然后计算签名的_S_值,以便:
S ≡ q-1 (Keccak256(m) + k * R)(mod p)
地点:
验证是签名生成函数的逆函数,使用_R_、S_值和公钥计算出一个值_Q,它是椭圆曲线上的一个点(签名创建时使用的临时公钥):
p>
Q ≡ S-1 * Keccak256(m) * G + S-1 * R * K(mod p)
地点:
如果计算出的点_Q_的x坐标等于_R_,则验证者可以断定签名有效。
请注意,在验证签名时,私钥既不知道也不泄露。
提示
ECDSA 必然是一个相当复杂的数学;完整的解释超出了本书的范围。许多优秀的在线指南一步一步地介绍它:搜索“ECDSA 解释”或试试这个:[]。
实践中的交易签名
为了生成有效交易,发起方必须使用椭圆曲线数字签名算法对消息应用数字签名。当我们说“签署交易”时,我们实际上是指“签署 RLP 序列化交易数据的 Keccak256 哈希”。签名应用于交易数据的哈希,而不是交易本身。
提示
在第 2,675,000 号区块交易区块哈希值如何生成,以太坊实施了“伪龙”硬分叉,除其他更改外,该硬分叉引入了包括交易重放保护在内的新签名方案。这种新的签名方案在 EIP-155 中指定(参见 参考资料)。此更改会影响签名过程的第一步,在签名之前将三个字段(v、r、s)添加到交易中。
要在以太坊中签署交易,发件人必须:
创建一个包含九个字段的交易数据结构:nonce、gasPrice、startGas、to、value、data、v、r、s
生成交易的 RLP 编码序列化消息
计算此序列化消息的 Keccak256 哈希
计算 ECDSA 签名,使用启动 EOA 的私钥对哈希进行签名
在交易中插入ECDSA签名计算的r和s值
原始交易创建和签名
让我们创建一个原始交易并使用 ethereumjs-tx 库对其进行签名。此示例的源代码位于 GitHub 存储库的 raw_tx_demo.js 中:
raw_tx_demo.js:在 JavaScript 中创建和签署原始交易
link:code/web3js/raw_tx/raw_tx_demo.js[]
在这里下载:
运行示例代码:
$ node raw_tx_demo.js
RLP-Encoded Tx: 0xe6808609184e72a0008303000094b0920c523d582040f2bcb1bd7fb1c7c1ecebdb348080
Tx Hash: 0xaa7f03f9f4e52fcf69f836a6d2bbc7706580adce0a068ff6525ba337218e6992
Signed Raw Transaction: 0xf866808609184e72a0008303000094b0920c523d582040f2bcb1bd7fb1c7c1ecebdb3480801ca0ae236e42bd8de1be3e62fea2fafac7ec6a0ac3d699c6156ac4f28356a4c034fda0422e3e6466347ef6e9796df8a3b6b05bed913476dc84bbfca90043e3f65d5224
使用 EIP-155 创建原始交易
EIP-155“简单重放攻击保护”标准在签名之前指定了重放攻击保护的交易编码,其中包括交易数据中的_链标识符_。这确保了为一个区块链(例如以太坊主网)创建的交易在另一个区块链(例如以太坊经典或 Ropsten 测试网)上无效。因此,在一个网络上广播的交易不能在另一个网络上广播,因此得名“重放攻击保护”。
EIP-155 在交易数据结构中添加了三个字段 v、r+ 和 +s。 r+ 和 +s 字段被初始化为零。这三个字段在编码和散列之前添加到交易数据中。因此,三个附加字段会更改交易的哈希值,稍后将应用签名。通过在签名数据中包含链标识符,交易签名可以防止任何更改,因为如果修改了链标识符,签名将无效。因此,EIP-155 使交易无法在另一条链上重播,因为签名的有效性取决于链标识符。
签名前缀字段+v+被初始化为链标识符,值为:
链
链 ID
以太坊主网
1
现代(过时),广阔
2
罗普斯滕
3
林克比
4
砧木主网
30
砧木测试网
31
高文
42
以太经典主网
61
以太坊经典测试网
62
获取私有测试网
1337
生成的交易结构经过 RLP 编码、散列和签名。签名算法也稍作修改,将链 ID 编码在 +v+ 前缀中。
更多详情,请参阅 EIP-155 规范: