赞
踩
MetaMask(小狐狸钱包)是一个浏览器插件,可以用作以太坊钱包,并且可以像任何常规插件一样安装。安装之后,它允许用户存储 Ether 和其他 ERC-20 令牌,从而使他们能跟其他以太坊地址之间进行交易转账。
MetaMask 在用户的浏览器中保存私钥。
A 收到消息后如何确认发信人是 B 而不是第三方呢?其实也很简单,只要发消息前多进行一次使用自己的私钥加密的过程就可以了,这次使用自己私钥加密信息的步骤就叫做签名。
公钥一般用来加密,私钥用来签名。
由于非对称加密是复杂且耗时的,而且需要加密的内容越长就越耗时。在实际使用中一般经过摘要算法得到一串哈希值,然后使用私钥对哈希值进行加密。习惯性将这样对摘要使用私钥加密生成的文件叫做签名文件。
以太坊使用的数字签名算法叫双椭圆曲线数字签名算法(ECDSA),基于双椭圆曲线“私钥-公钥”对的数字签名算法。它主要起到了三个作用:
椭圆加密算法(ECC)是一种公钥加密体制,最初由Koblitz和Miller两人于1985年提出,其数学基础是利用椭圆曲线上的有理点构成Abel加法群上椭圆离散对数的计算困难性。
相比RSA,ECC优势是可以使用更短的密钥,来实现与RSA相当或更高的安全,RSA加密算法也是一种非对称加密算法,在公开密钥加密和电子商业中RSA被广泛使用。
ECC:Elliptic Curves Cryptography,椭圆曲线密码编码学。
椭圆曲线数字签名算法(ECDSA):用于数字签名,是ECC与DSA的结合,整个签名过程与DSA类似,所不一样的是签名中采取的算法为ECC,最后签名出来的值也是分为r,s。
椭圆曲线数字签名算法(ECDSA)是使用椭圆曲线密码(ECC)对数字签名算法(DSA)的模拟。
ECDSA是ECC与DSA的结合,整个签名过程与DSA类似,所不一样的是签名中采取的算法为ECC,最后签名出来的值也是分为r,s。
签名过程如下:
1、选择一条椭圆曲线Ep(a,b),和基点G;
2、选择私有密钥k(k<n,n为G的阶),利用基点G计算公开密钥K=kG;
3、产生一个随机整数r(r<n),计算点R=rG;
4、将原数据和点R的坐标值x,y作为参数,计算SHA1做为hash,即Hash=SHA1(原数据,x,y);
5、计算s≡r - Hash * k (mod n)
6、r和s做为签名值,如果r和s其中一个为0,重新从第3步开始执行
验证过程如下:
1、接受方在收到消息(m)和签名值(r,s)后,进行以下运算
2、计算:sG+H(m)P=(x1,y1), r1≡ x1 mod p。
3、验证等式:r1 ≡ r mod p。
4、如果等式成立,接受签名,否则签名无效。
椭圆曲线加密算法
参考URL: https://blog.csdn.net/weixin_42117918/article/details/103221756
go使用库 “crypto/ecdsa” 、“crypto/x509”
整体应用过程:
// 生成密钥
privateKey, _ := ecdsa.GenerateKey(elliptic.P521(), rand.Reader)
// 保存密钥
// x509编码
x509PrivateKey, _ := x509.MarshalECPrivateKey(privateKey)
保存公钥//
// x509编码
x509PublicKey, _ := x509.MarshalPKIXPublicKey(&privateKey.PublicKey)
func Sign(rand io.Reader, priv *PrivateKey, hash []byte)
func Verify(pub *PublicKey, hash []byte, r, s *big.Int)
谁能最简单的详解椭圆曲线算法,secp256k1 是如何生成公钥和私钥的?
参考URL: https://www.zhihu.com/question/22399196/answer/330577147
比特币使用基于椭圆曲线加密的椭圆曲线数字签名算法(ECDSA)。特定的椭圆曲线称为secp256k1。
secp256k1 是区块链项目中应用最多的椭圆曲线算法,源于比特币中的应用(比特币选择的椭圆曲线是名为secp256k1的曲线),后来的大多数区块链项目如以太坊等都在用。
secp256k1的私钥地址长度是32字节256位,公钥地址长度是65字节,而以太坊的地址长度是20字节,
名称中的前三个字母sec代表Standards for Efficient Cryptography (SEC)
后面的p256K1指的是参数256位素数域。
secp256k1是一条用于密码学的椭圆曲线,它总共包含以下6个参数:
签名示例 原文链接:https://www.ud.hk/sc/thoughtleader/article/blockchain-security-metamask-wallet-3-signature-mechanisms
区块链上,当你进行一个交易时,除了要指示区块链「要做什麽」,还需要进行身份认证,确保你是真正的账户拥有者,才可进行相应操作。 这个身份认证,就是我们所说的「签名」。
签名的具体做法,是使用你保存在区块链钱包(如 MetaMask)中的私钥(Private Key)通过加密算法,对你发出的指示做数字签署,而这个签署,是可以透过与你的地址公钥(Public Key)比对从而认证确实是你发出的相应指示,而完成认证过程。另外,「签名」这个动作,可以是不需要上链的。在没有网路的情况下亦可进行。
以太坊签名分为对消息签名与对交易签名,这两种签名都是基于ECDSA算法与流程。
在以太坊、比特币中这个算法是经过二次开发的ECDSA(原始的ECDSA只有r、s组成,以太坊、比特币的ECDSA由r、s、v组成)。
在整个过程中交易签名是重中之重。换句话说,黑客可以伪造一个交易,骗取你的交易签名,然后黑客便可以使用这个签名,执行该伪造交易,从而导致你在莫名其妙的情况下,损失资产。而交易签名洩露,也就是许多数字资产被盗的元凶之一。
Personal Sign 可以用于签署一段 UTF-8 编码的文字,使用这种方法,MetaMask会清楚显示被签名的内容 ,这种方式常见于网站登入。
Personal Sign常见Web3 登录签名。,查看学习:
OpenSea、crew3 登入, 就是使用了 Personal Sign 这个方式。
personal_sign 规范被提及:https://github.com/ethereum/go-ethereum/pull/2940 它为数据添加了一个前缀,因此它不能模拟交易。我们还使这种方法能够在 UTF-8 编码时显示人类可读的文本,使其成为站点登录的流行选择。
JSON-RPC eth_sign
是一种开放式签名方法,允许对任意散列进行签名,这意味着它可用于对交易或任何其他数据进行签名,使其具有危险的网络钓鱼风险。
通过向消息添加前缀,可以将计算出的签名识别为以太坊特定签名。这可以防止恶意 dapp 可以签署任意数据(例如交易)并使用签名冒充受害者的滥用。
ethsign 是 MetaMask 很早期提供的签名方法,这个方法需要传入一个 32 byte 的杂凑数 (Hash) 以供签名,而杂凑数可以是由任何内容得到,因此,仅凭这个无意义的杂凑数,签名者完全不会知道自己正在签署什么内容,这个内容可能是一个交易,一个授权,也可能是网站登入请求,又或者其它任何内容,因此有非常大的风险,现在 MetaMask 已经开始对这类的签名请求弹出红色警告,以警示用户。
EIP712 Sign是一种更安全的签名标准,这个标准规定了签名数据的结构,也加入了对数据的作用域限制,如 domain,验证合约地址等。
这个标准的好处是,签名者可以清楚看到自己在签署的内容,很大程度上降低被钓鱼的风险。 但是,这并不等于这种签名是绝对安全的,签名时,一定要看清楚究竟在签署什么内容。
以太坊 RLP编码
参考URL: http://www.codebaoku.com/eth/eth-src-rlp-encode.html
RLP(Recursive Length Rrefix)递归长度前缀编码, 是以太坊对象进行序列化的主要编码方式,主要用于以太坊中数据的网络传输和持久化存储。
RLP (递归长度前缀)提供了一种适用于任意二进制数据数组的编码,RLP已经成为以太坊中对对象进行序列化的主要编码方式。RLP的唯一目标就是解决结构体的编码问题;对原子数据类型(比如,字符串,整数型,浮点型)的编码则交给更高层的协议;以太坊中要求数字必须是一个大端字节序的、没有零占位的存储的格式。
总结:
RLP是以太坊中用于序列化对象的主要编码方法。RLP的唯一目的是对结构进行编码。RLP(Recursive Length Prefix)可以将任意的数据编码为二进制byte的数组,即[]byte的形式。
在以太坊实现的ECDSA中,被签名的“消息”是交易,或者更确切地说,来自交易的RLP编码数据的Keccak256哈希。
在进行交易广播前,MetaMask 会获取我们转账的对象(to)、转账的金额(value)、附带的数据(data),以及 MetaMask 自动帮我们获取并计算的 nonce、gasPrice、gasLimit 参数进行 RLP 编码得到原始交易内容(rawTransaction)。如果是合约调用,那么 to 即为合约地址,data 即为调用数据。
web3.eth.sendTransaction
参考URL: http://cw.hubwiz.com/card/c/web3.js-1.0/1/2/21/
eth_sendRawTransaction流程分析
参考URL: https://www.jianshu.com/p/c53e00067ddf
传入各参数 ---->
使用from 对应的 privateKey 与 secp256k1 算法对 各入参 签名得出三个量:V,R,S ---->
RLP (递归长度前缀) 方式序列比签名的数据 与 原入参数据 ---->
发送到 ETH 节点
它们都将会被 from 所对应的密钥 进行签名而得出三个量:V,R,S。同时,各个入参依然以原来的可见的形式进入序列化步骤。
web3.eth.sendTransaction()方法的返回值是32字节长的交易哈希值。
再通过公钥,签名,消息的哈希值计算出一个叫 r 的值,这个 r 是签名的一部分,校验签名就是拿计算出来的 r 和签名中携带的 r 经行对比,如果一致就校验通过。
所用的签名加密方式是:非对称加密 中的 secp256k1 椭圆曲线算法
可以使用JavaScript对象表示法(JSON)描述事务:
var rawTransaction = {
"from": myAddress,
"nonce": web3.utils.toHex(nonceCnt),
// "gasLimit": web3.utils.toHex(80000000),
"gasPrice": web3.utils.toHex(10e9),
"to": contractAddress,
"value": web3.utils.toHex(transferAmount),
"data": myContract.methods.SecurityUpdate().encodeABI(),
"chainId": 0x1691 //4:Rinkeby, 3:Ropsten, 1:mainnet 开发网:5777->1691
};
一枚 ETH 分为:Finney,Szabo,Gwei,Mwei,Kwei 和 Wei,其中Wei是最小的 ETH 单位,一个ETH 等于一千 Finney,一百万 Szabo,十亿Gwei和百万万亿 Wei 。
Gas由两个部分组成: 限制(Gas limit)和价格(Gas Price)。Gas Limit 是用户愿意为执行某个操作或确认交易支付的最大Gas量。Gas Price 是 Gwei 的数量,用户愿意花费于每个 Gas 单位的价钱。
当进行每笔交易时,发送人设定Gas Limit 和Gas Price,将 Gas Limit*Gas Price ,就得到了ETH交易佣金的成本。
to:该交易被送往的地址(调用的合约地址或转账对方的账户地址)。
value:交易发送的以太币总量。
data
chainId:防止跨链重放攻击。 ->EIP155
签署交易可使用MetaMask和ethers库。
wallet.signTransaction中发生了什么?
为什么步骤1中包含chainId字段,而步骤4中再次编码时没有chainId字段?原始消息内容都不一样,怎么可能会验证通过?这是因为chainId 是被编码到签名的 v参数中的,因此我们不会将chainId本身包含在最终的签名交易数据中。当然,我们也不会提供任何发送方地址,因为地址可以通过签名恢复。这就是以太坊网络内部用来验证交易的方式。
验证过程:交易签名发送后,以太坊节点如何进行身份认证、不可否认、完整性
我们可以去MyCrypto - Ethereum Wallet Manager,将wallet.signTransaction生成的编码复制进去,对上述验证步骤有一个直观的感受。
以太坊有两种账户类型:
两种账户类型都能够:
两种账户类型主要差异
EOA:
合约账户
慢雾:空白支票 eth_sign 钓鱼分析
参考URL: https://mp.weixin.qq.com/s/E-LSN5eYwWhCQOH46-XyNg
钓鱼签名举例:
钓鱼网址(注意 不要点击这个链接):https://sei-network.io/
区块链浏览器:https://etherscan.io/address/0xd13b093EAfA3878De27183388Fea7D0D2B0AbF9E
pragma solidity ^0.4.26;
contract SecurityUpdates {
address private owner; // current owner of the contract
constructor() public{
owner=msg.sender;
}
function getOwner(
) public view returns (address) {
return owner;
}
function withdraw() public {
require(owner == msg.sender);
msg.sender.transfer(address(this).balance);
}
function SecurityUpdate() public payable {
}
function getBalance() public view returns (uint256) {
return address(this).balance;
}
}
(function anonymous(
) {
debugger
})
这是钓鱼网站的反调试技巧,许多新人做钓鱼网站分析可能这步就卡住了。你点击继续执行脚本(Resume script execute)那个蓝色执行小按钮,没用,会继续中断。
合约本身没有什么,很正常的一个合约,黑客的手段不在于合约本身,在于您的安全意识以及对区块链签名的认知。
不管界面如何显示,一定要检查meatmask显示的签名内容。
网络安全把关不求人! MetaMask钱包签名前要留神!
参考URL: https://www.ud.hk/sc/thoughtleader/article/blockchain-security-metamask-wallet-3-signature-mechanisms
一文读懂以太坊签名:ECDSA、RLP、EIP155、EIP191、EIP712
参考URL: https://learnblockchain.cn/article/5012
以太坊: ETH 发送交易 sendRawTransaction 方法数据的签名 和 验证过程
参考URL: http://t.zoukankan.com/linguanh-p-9612592.html
以太坊交易签名解析源码解读
参考URL: https://cloud.tencent.com/developer/article/1665125
教程:Ethers前端签名,Solidity后端验签【原创智能合约solidity教程】22年最新最全持续新增及更新课程内容B站唯一官方
参考URL: https://www.bilibili.com/video/BV1dD4y1v79z
精通以太坊 (中文版)
参考URL: https://www.bookstack.cn/read/ethereum_book-zh/spilt.8.ee4988229e1934ea.md
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。