当前位置:首页区块链以太坊数字签名技术解读

以太坊数字签名技术解读

密码签名是区块链的关键技术之一,它可以在不暴露私钥的情况下证明地址的所有权。这项技术主要用于签署交易(当然也包括其他任何消息)。本文将解释数字签名技术在以太坊协议中的应用。

免责声明:密码学很难。请不要将本文的任何内容作为实现您自己的加密函数的参考。虽然我们已经进行了广泛的研究,但文本提供的信息可能仍然不准确。本文仅作教育用途。

以太坊数字签名技术解读

什么是加密签名?

当我们谈论密码学中的签名时,我们实际上是在讨论所有权、有效性和完整性的证据。例如,这些签名可用于:

证明您拥有该地址的私钥(即认证功能);

确保信息(如邮件)不被篡改;

请验证您下载的mycrypto版本是否合法。

密码签名是基于数学公式的。如果我们有一个输入消息,一个私钥和(通常是秘密的)随机数,我们可以得到一个数字串作为输出值,即签名。另一个数学公式可以在不知道私钥和随机数的情况下进行反向计算和验证。这类算法有很多,如RSA和AES,但以太坊(和比特币)采用椭圆曲线数字签名算法(ECDSA)。请注意,ECDSA只是一个签名算法。与RSA和AES不同,该算法不能用于加密。

以太坊数字签名技术解读1

-椭圆曲线的一个例子。以太坊采用secp256k1曲线。-

通过椭圆曲线点操作,可以利用私钥计算出一个不能反算的值。通过这种方式,我们可以创建安全和防篡改的签名。能产生非逆计算值的函数称为陷门函数

陷门函数是指在一个方向上容易计算,但在没有特殊信息(即陷门)的情况下很难反求的函数。

使用ECDSA签名和验证

ECDSA签名由两个数字(整数)组成:R和s。以太坊还引入了一个附加变量V(恢复标识符)。签名可以表示为。

创建签名时,应首先准备要签名的消息和用于签名消息的私钥(Dₐ)。简化签名流程如下:

哈希签名消息并获得哈希值(E)。

生成安全随机数K。

椭圆曲线上的点(x₁,y₁)通过K乘以椭圆曲线的常数g来计算。

计算r=x₁mod n。如果r=0,则返回步骤2。

计算s=k⁻(E+Rdₐ)mod n。如果s等于0,则返回步骤2。

在以太坊上,哈希值通常使用keccak256(quot;/x19ETHereum签名消息:n32quot;+keccak256(消息))计算。这确保签名不能在以太坊之外使用。

由于K是一个随机值,我们每次都会得到不同的签名。如果K的随机性不够高,或者随机值被泄露,则可以使用两个不同的签名来计算私钥[“故障攻击”]。但是,如果每个消息的输出密码值相同,如何确保其安全性?这些确定性签名基于RFC 6979标准。该标准描述了如何基于私钥和消息(或哈希)生成安全K值。

签名可以形成一个65字节的序列:R有32个字节,S有32个字节,V有1个字节。如果我们把签名编码成一个十六进制的字符串,**得到一个130个字符的字符串。大多数钱包和接口都使用这个字符串。以mycrypto为例。完整的签名如下图所示:

{
quot;地址quot;:quot;0x76e01859d6cf4a8637350bdb81e3cef71e29b7c2quot;,
quot;msgquot;:quot;你好世界!quot;,
quot;sigquot;:quot;0X21FBF0696D5E0AA2EF41A2B4FFB623BCAF72461CF725C74161F82FEC3A4370854BC0A34B3B487C1BC021CCD318C734C51AE29374F2BEB0E6F2DD49B4BF41Cquot;,
quot;版本6035:quot;2quot;
}

在mycrypto的verify message页面中,我们可以使用签名,并看到消息是由0x76e01859d6cf4a8637350bdb81e3cef71e29b7c2签名的。

以太坊数字签名技术解读2

-mycrypto上的签名已验证。点击这里体验。-

您可能会问:为什么还要包括其他信息,如地址、消息和版本?就不能验证签名本身吗?好吧,不。如果你不保留其他信息,就像签了一份合同,然后删除合同中的所有信息,只留下双方的签名。与事务签名(稍后我们将更详细地解释)不同,消息签名只是签名。

要验证消息,我们需要知道原始消息、使用私钥对消息签名的地址以及签名本身。版本号是mycrypto使用的版本号。旧版本的mycrypto通常会添加消息的当前日期和时间,计算其哈希值,然后根据上述步骤对消息进行签名。它后来被更改为符合on-rpc方法personal_Sign方法,因此需要指定版本号(“2”)。

简化的公钥恢复过程如下:

计算消息的哈希值(E)。

计算椭圆曲线上的点r=(x₁,y₁),其中x₁是r(v=27)或r+n(v=28)。

计算u₁=-Zr⁻Ψmod n和uΨ=SR⁻dle mod n。

计算点Qₐ=(xₐ,yₐ)=u₁×G+uΨ×R。

Qₐ是与用于签名的地址的私钥相对应的公钥。我们可以根据公钥计算地址,并检查地址是否与提供的地址匹配。如果匹配,则签名有效。

恢复标识符(“V”)

V是签名的**一个字节,为27(0x1b)或28(0x1c)。由于采用了椭圆曲线算法,因此对标识符的恢复非常重要。我们只能通过R和S计算曲线上的多个点,因此我们可以恢复两个不同的公钥(及其对应的地址)。V将告诉我们应该使用这些要点中的哪一个。

在大多数实现中,V在内部只有0或1,而27是比特币消息签名时添加的任何数字。以太坊也接受了这一点。

从eip-155开始,我们还使用链ID来计算V值。这可以防止跨链重播攻击:在以太坊上签名的事务不能在以太坊经典版上使用,反之亦然。目前,恢复标识符仅用于签署事务,而不是消息。

签署协议

到目前为止,我们只关注消息的签名。就像消息一样,事务需要在发送之前进行签名。如果你使用像ledger和trezor这样的硬件钱包,签名过程发生在硬件内部。如果使用私钥(或keystore文件,助记符),可以直接在mycrypto上签名。这与交换签名消息的方式非常相似,只是略有不同。

要签名的交易使用RLP编码进行编码,包括所有交易参数(nonce、gas price、gas limit、to、value、data)和签名(V、R、s)。签署的交易如下:

0xF86C0A8502540BE400825208944BEB066ED09B7AED07BF39EEE0460DFA2615208080DE0B6B3A7640000801CA0F3AE52C1EF3300F44DF0BCFD1341C232ED6134672B16E35699AE3F2493379A023D2955A239DD6F61C4E8B267D174356FF424EA53E17706C43EF871

如果我们在mycrypto的签名交易广播页面上输入交易,我们将看到所有交易参数:

以太坊数字签名技术解读3

-mycrypto签名事务广播页面上的事务参数概述-

已签名事务的第一组字节包含RLP编码的事务参数,**一组字节包含事务的签名。我们可以通过以下方式对签名交易进行编码:

事务参数:RLP(nonce,gasprice,gaslimit,to,value,data,chainid,0,0)事务参数。

keccak256算法用于计算RLP编码的非签名事务的哈希值。

根据上述步骤,哈希值通过ECDSA算法与私钥签名。

对签名的事务进行编码:RLP(nonce、gasprice、gaslimit、to、value、data、V、R、s)。

对RLP编码的事务数据进行解码后,可以得到原始的事务参数和签名。

请注意,链ID被编码到签名的V参数中,因此我们不会在最终签名事务数据中包含链ID本身。我们不会提供任何发件人的地址,因为地址可以通过签名恢复。以太坊网络就是这样用来验证交易的。

签名报文标准化

关于如何为人们定义消息结构,有很多建议。到目前为止,还没有**确定任何建议。最初由gETH personal实施,目前最常见的还是标牌格式。不过,有些建议还是很有意思的。

让我简单介绍一下当前创建签名的方法:

quot;/x19ETHereum签名消息:/nquot;+长度(消息)+消息

消息通常事先经过哈希处理,因此长度固定为32字节:

quot;/X19以太坊签名消息:/n32quot;+Keccak256(消息)

对完整的消息(包括前缀)再次进行哈希处理,然后用私钥对哈希值进行签名。这种方法适用于所有权证明,但在其他情况下可能会出现问题。例如,如果用户a签署消息并将其发送到合同X,则用户B可以**签名的消息并将其发送给合同y。这称为重播攻击。例如,EIP有191个提案。

EIP 191:签名数据标准

提案定义了一个非常简单的版本,即EIP编号。格式如下:

0x19lt;1字节版本gt;lt;版本特定数据gt;要签名的数据gt;

顾名思义,特定于版本的数据取决于我们使用的版本。目前,EIP 191有三个版本:

0x00:带有“预期验证器”的数据。如果是合同,则可以是合同地址。

0x01:结构化数据,如eip-712所定义。稍后将对此进行详细解释。

0x45:常规签名消息,例如个人签名当前的行为。

如果我们指定目标验证器(例如,契约地址),契约可以使用它自己的地址来重新计算散列值。无法将已签名的消息提交到另一个协定实例,因为后者无法验证签名。

由于已选择0x19作为固定字节前缀,签名消息不能是RLP编码的签名事务,因为后者从不以0x19开头。

EIP 712:基于以太坊的类化结构化数据哈希和签名

请不要混淆EIP 712和ERC 721。EIP 712是“键入”签名数据的建议。数据可以以人类可读的方式呈现,这可以降低数据验证的难度。

以太坊数字签名技术解读4

-通过metamask对消息进行签名。左侧是签名消息接口的旧版本(使用右侧的personal_u是新版本的接口(使用eip-712)。-

Eip-712定义了一种新的替换个人签名的方法:ETH-Signtypeddata(**版本使用ETH-Signtypeddata v4)。如果使用此方法,则必须指定所有属性(例如,to、amount和nonce)及其各自的类(例如address、uint256和uint256),以及一些关于应用程序的基本信息,称为域。

域包含诸如应用程序名称、版本、链ID、与之交互的合同和salt值等信息。合同应核实这些信息,以确保同一签名不能用于不同的应用程序。这可以解决上述重放攻击。

上图中消息的具体定义如下:

{
类:{
-EIP712Domain:[
{名称:{39;名称#39;名称〈39;39;起,类:#39;字符串#39;39;39;39;版本〈39;版本#39;39;;类:#39;字符串#39;39;}持久、
{名称:#39;39;链条ID#39;链条ID#39;39;除此之外,类:{39;39;链条ID〈39;39;39;39;主要#39;uint256#39;},
{姓名:#39;验证合同#39;,类:#39;地址#39;},
{姓名:#39;salt#39;,类:#39;bytes32#39;}
],
交易:
交易:[
{名称:〈39;到〈39;的〈39;的〈39;、类:39;地址和〈39;39;39;}的主要是,
{名称:39;金额和#39;39;金额和#39;39;这一点,类:类:(假若39;39;UIT256“39;39;39;39;39;39;39;39;39;改;改;类:(假若#39;39;非正正正期和假若39;39;类方面,类:(39;39;UIT256和〈39;UIT256;39;39;39#39;}
]
},
域:{
名称:#39;MyCrypto#39;,
版本:#39;1.0.0#39;,
链ID:1,
验证合同:#39;0x098D8D8B363933D742476D594C4A5A5A5F1A62326A(39;,
盐分:39;0x76E22A2A8E58573472B9D7B73C41EE29160BC275919595434C1CB1201AE4769AFD7(39;
},
主类:#39;
},
primaryType:(39;交易(39;39;39;39;
9;
;消息:{
-to:〈39;39;0x4BBBEB066EDEDED〈
至:〈39;39;0x4BBBEBEBEB066EDEDE09B7AED07BF39EEE0460DFA261520#39;,
金额:1000000,
nonce:0
}
}

-来源-

如您所见,此消息在metamask上可见,我们可以确认我们要签名的消息是我们想要执行的。EIP 712实现EIP 191,因此数据将以0x1901开头:0x19是前缀,0x01是版本字节,表示这是EIP 712签名。

通过SOLidness,我们可以为事务类定义一个结构,并编写一个函数来散列事务:

struct Transaction{
应付地址;
uint256 amount;
uint256 nonce;
}
函数hashTransaction(事务调用数据事务)公共视图返回(bytes32){
return keccak256(
二进制编码压缩(
字节(0x19),
字节(0x01),
域分隔符,
事务类,
keccak256(
abi.编码(
)事务处理。收件人,
交易金额,
事务处理.nonce



);
}

上述交易的数据如下:

0x1901FB502C9363785A728BF2D9A150FF634E6C6EDA4 A88196262E490B191D5067CCEE82DAAE26B730CAEB3F79C5C62CD998926589B40140538F456915AF319370899015D824EDA913CD3BFC2991811B95551632F2EF14FE0DA1B3BC4C0F424929

以上数据由eip-191字节、哈希字段分隔符、哈希事务类和事务输入组成。数据被再次散列并签名。然后,我们可以使用ecrecover来验证智能合约中的签名:

函数验证(地址签名者,事务调用数据事务,bytes32r,bytes32s,uint8 v)公共返回(bool){
return signer==ecrecover(hashTransaction(Transaction),v,r,s);
}

在下一节中,我们将详细解释ecrecover。如果您想找到一个简单的JavaScript或typescript代码库来实现eip712,请检查此库:

https://github.com/Mrtenz/eip-712

如果您想了解有关如何在智能合约中实现EIP 712的更多信息,我建议您通过metamask阅读本文。不幸的是,EI712规范草案还没有得到很多应用程序的支持。目前,ledger和trezor都不支持eip712,这可能会阻碍其广泛采用。不过,莱杰表示,他们即将发布的更新将支持EIP712。

通过智能合约验证签名

关于消息签名更有趣的是,我们可以使用智能合约来验证ECDSA签名。Solidity有一个内置函数ecrecover(实际上是地址0x1的预编译协定),用于恢复用于签名消息的私钥的地址。基本合同执行情况如下:

//SPDX许可证标识符:MIT
pragma SOLidity 0.7.0;
合同签名器{
/**
*@通知恢复ECDSA签名和消息哈希的地址,请注意,哈希将自动以quot;/x19ETHereum签名消息作为前缀:/n32quot;
*@return address用于对消息
*/
函数recoverAddress进行签名的地址(bytes32 hash,uint8 v,bytes32 r,bytes32 s)公共纯返回(address){
bytes memory prefix=quot;/x19ETHereum签名消息:/n32quot;;
bytes32 prefixedHash=keccak256(二进制编码压缩(prefix,hash));
返回ecrecover(prefixedHash,v,r,s);
}
/**
*@注意检查从ECDSA签名恢复的地址是否等于提供的地址“signer”
*@return valid提供的地址是否与签名
匹配*/
函数是否有效(地址签名者、字节32哈希、uint8 v、bytes32 r、bytes32 s)外部纯返回(bool){
return recoverAddress(hash,v,r,s)==签名者;
}
}

契约只用于验证签名,它本身没有用处,因为签名验证也可以在没有智能合约的情况下完成。

这种方法的用途是,用户可以在不发送事务的情况下,以无信任的方式向智能合约发送一些指令。例如,用户可以签署消息:“请从我的地址向该地址发送1以太。”智能合约可以使用eip-712和/或eip-1077标准验证签名者并执行指令。智能合约中的签名验证可用于以下应用:

签署多个合同(如gnosis safe);

去中心化的交流;

元交易和天然气中继(如加油站网络)。

但是如果你想通过你正在使用的智能合约钱包签署信息呢?我们显然不能让钱包智能合约访问私钥,对吧。ERC 1271提出了智能合约的标准,以验证其他智能合约的签名。规格非常简单:

pragma SOLidity^0.7.0;
contract ERC1271{
bytes4常量内部MAGICVALUE=0x1626ba7e;
函数isValidSignature(
bytes32 uHash,
bytes memory u signature
)公共视图返回(bytes4 MAGICVALUE);
}

合同必须实现isvalidsignature功能,该功能可以运行上述任何功能。如果签名确实与合同对应,则函数将返回magicvalue。这样,任何实现ERC1271的合同都可以验证其签名。在内部,实现ERC1271的契约允许多个用户签署同一条消息(例如,在多个契约的情况下)并在内部存储散列值。然后,合同可以验证提供给isvalidsignature函数的哈希值是否在内部签名,以及签名是否对其中一个合同所有者有效。

总结

对于区块链和去中心化,签名非常重要。签名不仅可以用于发送事务,还可以用于与去中心化交换、多重签名合同和其他智能合约进行交互。目前,对消息签名还没有明确的标准。进一步采用EIP712规范将有助于生态系统改善用户体验,并制定消息签名标准。

参考文献及相关文章

以太坊:一种安全的去中心化通用交易账本(黄皮书)

EIP-155:简单重放攻击保护

EIP-191:签名数据标准

EIP-712:以太坊类的结构化数据哈希和签名

ERC-1271:合同的标准签名验证方法

RFC6979:数字签名算法(DSA)和椭圆曲线数字签名算法(ECDSA)的确定性用法

温馨提示:

文章标题:以太坊数字签名技术解读

文章链接:https://www.btchangqing.cn/127337.html

更新时间:2020年10月22日

本站大部分内容均收集于网络,若内容若侵犯到您的权益,请联系我们,我们将第一时间处理。

区块链

叠加效应+乘数效应,商业密码和区块链,推动数字经济发展

2020-10-22 14:05:57

区块链

Burkhard Balz:CBDC作为一种价值储备,对金融体系构成威胁

2020-10-22 14:14:54

0 条回复 A文章作者 M管理员
    暂无讨论,说说你的看法吧
个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索