[md]
keystore钱包文件
鉴于私钥的重要性,我们需要以一种安全地方式保存它,而不是简单地 存到一个文件里。
keystore允许你用加密的方式存储密钥。这是安全性(一个攻击者需要 keystore 文件和你的钱包口令才能盗取你的资金)和可用性(你只需要keystore 文件和钱包口令就能用你的钱了)两者之间完美的权衡。
下图是一个keystore文件的内容:
keystore
从图中可以看出,keystore的生成使用了两重算法:首先使用你指定的钱包口令 采用kpf参数约定的算法生成一个用于AES算法的密钥,然后使用该密钥 结合ASE算法参数iv对要保护的私钥进行加密。
由于采用对称加密算法,当我们需要从keystore中恢复私钥时,只需要 使用生成该钱包的密码,并结合keystore文件中的算法参数,即可进行 解密出你的私钥。
这一部分我们直接基于nebulasio 的实现代码进行简单封装,得到KeyStore实现类,它有两个静态方法:
KeyStore::save($privateKey,$pass,$walletDir)
KeyStore::load($pass,$walletFile)
例如,下面的代码使用口令123将私钥存入./keystore目录,并返回钱包文件名:
【demo: repo\chapter3\wallet.php】
<?php
require('../vendor/autoload.php');
use Elliptic\EC;
use kornrunner\Keccak;
use EthTool\KeyStore;
$ec = new EC('secp256k1');
$keyPair = $ec->genKeyPair();
//创建一个新的私钥
$privateKey = $keyPair->getPrivate()->toString(16,2);
//定义随意的密码123
$wfn = KeyStore::save($privateKey,'123','./keystore');
echo 'private key: ' . $privateKey . PHP_EOL;
echo 'wallet file: ' . $wfn . PHP_EOL;
$recovered = KeyStore::load('123',$wfn);
echo 'recovered key: ' . $recovered . PHP_EOL;
?>
下面的代码使用口令123从钱包文件恢复出私钥:
【demo: repo\chapter3\credential.php】
<?php
require('../vendor/autoload.php');
use EthTool\Credential;
//传入之前的密码 123 和keystore路径
$wfn = Credential::newWallet('123','./keystore');
$credential = Credential::fromWallet('123',$wfn);
echo 'private: ' . $credential->getPrivateKey() . PHP_EOL;
echo 'public: ' . $credential->getPublicKey(). PHP_EOL;
echo 'address: ' . $credential->getAddress() . PHP_EOL;
?>
Credential账户凭证
为了方便后续的使用,我们实现了一个账户凭证类,来封装密钥对的生成、 钱包的生成与加载、裸交易的签名等操作:
Credential类提供了4个静态方法用来创建实例或钱包文件。例如:
use EthToolCredential;
$credential = Credential::new(); //生成新的密钥对并返回实例
$credential = Credential::fromKey('0x19....'); //导入指定私钥并返回实例
$credential = Credential::fromWallet('123','./keystore/1983...'); //从钱包载入实例
Credential::newWallet('123','./keystore/'); //创建一个新的钱包并返回文件名
Credential对象有3个方法,分别用来获取私钥、公钥和账户地址。例如:
echo $credential->getPrivateKey() . PHP_EOL; //获取私钥
echo $credential->getPublicKey() . PHP_EOL; //获取公钥
echo $credential->getAddress() . PHP_EOL; //获取地址
在后续的课程中,我们将需要使用私钥对裸交易进行签名:
$signed = $credential->signTransaction($raw); //签名交易
执行 chapter3/wallet.php
如有代码报错:Fatal error: Uncaught Error: Call to undefined function EthTool\scrypt()
PHP安装scrypt扩展
在官方下载http://pecl.php.net/package/scrypt
找到自己的php版本对应的版本,我的是
window.xampp。 所以选择线性安全版本:
下载后把文件:C:\Users\rui\Desktop\php_scrypt-1.4.2-7.2-ts-vc15-x64\php_scrypt.dll
拷贝到 xampp目录:C:\xampp\php
配置 C:\xampp\php\php.ini
在extension下面加入:extension=php_scrypt
重启xampp
最终显示
$ php wallet.php
private key: 0b06d6f4143e364bea3e450351858d55dc8e31d83e0bf0d351587ca4ed116f4d
wallet file: ./keystore/79fabf1dbcb7d90a746a4e01267b1a455c9153cf.json
recovered key: 0b06d6f4143e364bea3e450351858d55dc8e31d83e0bf0d351587ca4ed116f4d
下一篇:5.以太坊php web3:为网站增加以太币支付功能