对待签署消息进行哈希计算,得到哈希值(e)。 生成一个安全的随机数 k。 将 k 乘以椭圆曲线的常量 G,来计算椭圆曲线上的点(x?, y?)。 计算 r = x? mod n。如果 r 等于 0,请返回步骤 2 。 计算 s = k??(e + rd?) mod n。如果 s 等于 0,请返回步骤 2。 在以太坊上,通常使用 Keccak256("\x19Ethereum Signed Message:\n32" + Keccak256(message))来计算哈希值。这样可以确保该签名不能在以太坊之外使用。 由于 k 是随机值,我们每次得到的签名都不一样。如果 k 的随机程度不够高,或者随机值被泄漏,就有可能使用两个不同的签名计算出私钥【“fault attack”】。但是,如果你在 MyCrypto 内签署同一条消息,每次得到的输出值都相同,那么如何确保其安全性?这些确定性签名均采用 RFC 6979 标准。该标准描述了如何基于私钥和消息(或哈希值)来生成安全的 k 值。 {r, s, v} 签名可以组成一个长达 65 字节的序列:r 有 32 个字节,s 有 32 个字节,v 有一个字节。如果我们将该签名编码成一个十六进制的字符串,我们最后会得到一个 130 个字符长的字符串。大多数钱包和界面都会使用这个字符串。以 MyCrypto 为例,一个完整的签名如下图所示: {"address": "0x76e01859d6cf4a8637350bdb81e3cef71e29b7c2","msg": "Hello world!","sig": "0x21fbf0696d5e0aa2ef41a2b4ffb623bcaf070461d61cf7251c74161f82fec3a4370854bc0a34b3ab487c1bc021cd318c734c51ae29374f2beb0e6f2dd49b4bf41c","version": "2"} 在 MyCrypto 的 “验证消息(Verify Message)” 一页中,我们可以使用该签名,并看到该消息是由 0x76e01859d6cf4a8637350bdb81e3cef71e29b7c2 签署的。 - MyCrypto 上的签名验证通过。点击此处,即可体验。 - 你可能会问:为什么要将 address、msg 和 version 等其它信息也包括在内?不能只验证签名本身吗?好吧,不能。如果不保留其它信息,就好像签了一个合同,然后删除了合同里的所有信息,只留下当事人的签名。不同于交易签名(我们之后会作更深入解释),消息签名就只是签名而已(译者注:因此只有签名是没法验证的)。 为了验证消息,我们需要掌握原始消息、使用私钥签署消息的地址,以及 {r, s, v} 签名本身。版本号就是 MyCrypto 使用的某个版本号。旧版本的 MyCrypto 通常会加上消息的当前日期和时间,计算其哈希值,然后按照上述步骤签署该消息。后来又进行了更改,以符合 JSON-RPC 方法personal_sign 方法,因此需要指明版本号(“2”)。 (责任编辑:admin) |