科普|以太坊私钥存储文件

我们都知道,在区块链的世界中,私钥是你有用某一地址的唯一标识。丢失了私钥就等于丢失了此地址的所有权。

以太坊私钥存储

以太坊的私钥文件存储于数据目录(datadir指向或默认目录)下,对应的目录为keystore。所有的私钥文件都经过加密之后存储于此目录下。

以太坊的客户端或图形界面帮助我们因此了底层复杂的密码实现,唯一需要我们做的就是保存好(多出备份)keystore下面的加密私钥文件和加密的密码。否则,有可能失去辛苦挖来的以太币或花钱购买来的以太币。

记住,永远不要犯的错误:丢失keystore文件或忘记密码!

以太坊创建账户

以太坊创建账户的操作非常简单,但有不同的展现形式。以geth客户端为例。

command命令方式

bogon:geth zzs$ ./geth account new
Your new account is locked with a password. Please give a password. Do not forget this password.
Passphrase:
Repeat passphrase:
Address: {0f7b73f3034d0d17a165e4cf50bd77051235b4e6}

bogon:geth zzs$ ./geth account list
Account #0: {0f7b73f3034d0d17a165e4cf50bd77051235b4e6} keystore:///Users/zzs/Library/Ethereum/keystore/UTC--2018-02-21T02-56-46.285140000Z--0f7b73f3034d0d17a165e4cf50bd77051235b4e6
bogon:geth zzs$

以上操作是直接执行geth客户端的命令(command)来创建账户和展示账户私钥文件信息。创建过程中需要两次输入对私钥加密的密码。此种方式的好处是不需要单独启动geth节点即可创建完成账户。

console命令方式

此种方式需先启动geth节点,并进入console命令行交互界面。然后执行以下命令:

> personal.newAccount("123456")
"0x00fe1b8a035b5c5e42249627ea62f75e5a071cb3"

// 或

> personal.newAccount()
Passphrase:
Repeat passphrase:
"0x6a787f16c2037826fbc112c337d7b571bb19c022"

通过personal角色来管理和创建新账号,并设置密码。

keystore文件

keystore文件是你独有的,用于签名交易的以太坊私钥的加密文件。一旦丢失文件或加密密码就意味着你失去了此地址发起交易、签名交易的特权,账户里面的资金将永远被锁。

keystore文件存在的价值就是以加密的方式存储密钥,同时在使用的时候只需要提供keystore文件和对应的密码即可发起交易。安全性与可用性达到了完美的平衡。

但是,我们需要注意的是一旦用密码对加密文件进行解锁之后,在有效时间内通一个客户端下,你可以发起交易,如果别人可以访问你的客户端,同样也可以发起交易。在网络安全不足的情况下,这是被盗币的场景之一。

秘钥文件内容

秘钥文件为文本文件,可以使用任何文本编辑器或浏览器打开。

bogon:keystore zzs$ cat UTC--2018-02-21T03-01-27.385349000Z--6a787f16c2037826fbc112c337d7b571bb19c022

{
    "address": "6a787f16c2037826fbc112c337d7b571bb19c022",
    "crypto": {
        "cipher": "aes-128-ctr",
        "ciphertext": "8ed39b22ab67a787baa4ebb545382255f747328e2a3e2e74970a0f66b422d169",
        "cipherparams": {
            "iv": "8e0e0905919d6d1669957fdf65f114ce"
        },
        "kdf": "scrypt",
            "kdfparams": {
            "dklen": 32,
            "n": 262144,
            "p": 1,
            "r": 8,
            "salt": "a2a84d4843dbcb7c0aefa933f37ead073aefe8503ac8497b77828e85467c6822"
        },
        "mac": "1fc4a5d260fdd70e772fdc9a28614e82d5ff0adc6c98332f8455c5aa0a3352ad"
    },
    "id": "7bce1a69-79a2-429a-836c-cc2bf72c80de",
    "version": 3
}

通过文件中的内容,我们能看到的是一个json字符串,里面包含了此秘钥对应的地址和加密相关的一些信息。

  • cipher:加密算法,对称加密,AES算法,用于加密以太坊私钥;
  • cipherparams:cipher算法需要的参数,参数iv,是aes-128-ctr加密算法需要的初始化向量;
  • ciphertext:加密后的密文,aes-128-ctr函数的加密输入密文;
  • kdf:秘钥生成函数,用于使用密码加密keystore文件;
  • kdfparams:kdf算法所需要的参数;
  • mac:验证密码的编码;

原理解析

加密秘钥

一个以太坊账户是由一对公私钥对构成,并使用强对称算法(cipher)进行加密。

我们看一下具体的流程图《ciphertex密文的对称解密》:

image

客户端读取密钥文件和加密密码,对私钥进行解密,然后使用私钥对发送的交易进行签名。

密码保护

以太坊使用基于密码保护的机制来解密密钥。这样用户就不需要记住一串非用户友好的密码。为了达到此效果,以太坊使用密钥生成函数,根据输入的密码和一系列参数就能计算解密密钥。

这就涉及到kdf和kdfparams的用途:

  • kdf是一个密钥生成函数,根据密码计算(或者取回)解密密钥。kdf用的是scrypt算法。
  • kdfparams是scrypt函数需要的参数。更多的参数可以参考:https://tools.ietf.org/html/rfc7914

用kdfparams参数对scrypt函数进行调整,反馈密码中,得到解密密钥,也就是密钥生成函数的输出。
image

错误密码

当输入错误密码时,密码派生和解密等操作都会成功,但最终计算所得的以太坊私钥不是正确的,因此无法进行解锁账户的操作。

keystore文件中mac值起作用的地方。在密钥生成函数执行之后,它的输出(解密密钥)和ciphertext密文就被处理,并且和mac(类似于数据签名)作比较。如果结果和mac相同,那么密码就是正确的,可以开始解密操作。

在和mac进行比较之前,需要解密密钥(左起第二字节开始的16字节)要和ciphertext*密文连接在一起,并进行哈希散列(用SHA3-256的方法)。

image

流程回顾

输入密码,密码作为kdf密钥生成函数的输入,计算解密密钥。用解密密钥和ciphertext密文连接并进行处理,和mac比较确保密码正确。最后,通过cipher对称函数用解密密钥对ciphertext 密文解密。

image

更多资讯

**获取更多资讯,请关注微信公众号:程序新视界。或加入QQ技术交流群:659809063。
本人诚接以太坊相关研发及技术支持(以太坊接口封装&代币开发等),如有需要请联系QQ:541075754。非诚勿扰。**
这里写图片描述

获得一对一技术咨询请扫码加入知识星球(小密圈)
这里写图片描述

  • 3
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
以太坊地址和公钥是通过椭圆曲线加密算法生成的。在以太坊中,每个账户都有一个唯一的以太坊地址和公钥。 以太坊的公钥和私钥也是通过椭圆曲线加密算法生成的。私钥用于对数据进行加密,公钥用于对数据进行解密。 下面是一个简单的示例,展示如何使用以太坊的公钥和私钥对数据进行加解密: 1. 生成公钥和私钥以太坊中,可以使用任何一个以太坊钱包生成公钥和私钥。例如,可以使用 MetaMask 钱包生成公钥和私钥。 2. 加密数据 要加密数据,可以使用以太坊的公钥和私钥。以下是一个示例加密函数: ```solidity function encrypt(string memory message, address publicKey) public view returns (bytes32) { bytes32 encrypted = keccak256(abi.encodePacked(message, publicKey)); return encrypted; } ``` 在这个函数中,我们使用 keccak256 哈希函数对消息和公钥进行加密。 3. 解密数据 要解密数据,可以使用以太坊的公钥和私钥。以下是一个示例解密函数: ```solidity function decrypt(bytes32 encrypted, address privateKey) public view returns (string memory) { bytes32 decrypted = keccak256(abi.encodePacked(encrypted, privateKey)); return string(decrypted); } ``` 在这个函数中,我们使用 keccak256 哈希函数对加密后的消息和私钥进行解密。 请注意,这只是一个简单的示例,实际上在以太坊中使用公钥和私钥进行加解密需要更多的安全措施和实现细节。建议在使用以太坊的公钥和私钥进行加解密时,始终遵循最佳实践和安全标准。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序新视界

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值