进入keystore管理以太坊私钥的障碍很大,主要是由于以太坊客户端在直接的命令行或图形界面下隐藏了大部分的密码复杂性。html
例如,用geth:git
$ geth account new Your new account is locked with a password. Please give a password. Do not forget this password. Passphrase: Repeat passphrase: Address: {008aeeda4d805471df9b2a5b0f38a0c3bcba786b} $ geth account list Account #0: {8a1c4d573cc29a96547816522cfe0b266e88abac} keystore:~/.ethereum/keystore/UTC--<created_date_time>-- 008aeeda4d805471df9b2a5b0f38a0c3bcba786b
我只须要输入3个单词就能建立一个新帐户。而后输入两遍密码,就这么简单!个人以太坊keystore文件就建立了。github
你须要把那些很是珍贵的keystore文件备份、存储在一个或多个隐秘的位置,这样就只有你能获取这些文件并取到资金。算法
从经验来看,当我没有彻底理解一个新概念的微妙之处,而且过度依赖抽象层和现有工具来让个人生活更轻松时,我颇有可能忘记一些事情,采起没必要要的捷径而且搞砸它。搞砸的时候,可能就是会以我辛苦挣来的以太币被永久锁定而了结(幸亏它尚未发生!)。安全
幸运的是,做为一个以太坊用户,你能搞砸的方式并很少:函数
在本文中,咱们将为你介绍以太坊私钥是如何从 keystore 文件中算出来的。咱们将讨论加密函数(对称加密,密钥生成函数,SHA3 哈希算法),但咱们会尽量的保证简明直接地来解释上述问题。工具
以太坊的 keystore 文件(Linux 系统存储在 ~/.ethereum/keystore 或者 Windows 系统存储在 C:\Users<User>\Appdata/Roaming/Ethereum/keystore)是你独有的、用于签署交易的以太坊私钥的加密文件。若是你丢失了这个文件,你就丢失了私钥,意味着你失去了签署交易的能力,意味着你的资金被永久的锁定在了你的帐户里。this
固然,你能够直接把你的以太坊私钥存储在一个加密文件里,可是这样你的私钥容易受到攻击,攻击者简单的读取你的文件、用你的私钥签署交易,把钱转到他们的帐户中。你的币会在你意识到发生什么了以前的短期内丢失。加密
这就是以太坊 keystore 文件被建立的缘由:它容许你以加密的方式存储密钥。这是安全性(一个攻击者须要 keystore 文件和你的密码才能盗取你的资金)和可用性(你只须要keystore文件和密码就能用你的钱了)二者之间完美的权衡。命令行
为了让你发送一些以太币,大多数的以太坊客户端会让你输入密码(与建立帐户时密码相同)以解密你的以太坊私钥。一旦解密,客户端程序就获得私钥签署交易,容许你移动资金。
若是你打开一个你的帐户文件,它看起来像这样(取自这里):
ount’s file, it would look like this (taken from here):
$ cat ~/.ethereum/keystore/UTC--<created_date_time>-- 008aeeda4d805471df9b2a5b0f38a0c3bcba786b { "crypto" : { "cipher" : "aes-128-ctr", "cipherparams" : { "iv" : "83dbcc02d8ccb40e466191a123791e0e" }, "ciphertext" : "d172bf743a674da9cdad04534d56926ef8358534d458fffccd4e6ad2fbde479c", "kdf" : "scrypt", "kdfparams" : { "dklen" : 32, "n" : 262144, "r" : 1, "p" : 8, "salt" : "ab0c7876052600dd703518d6fc3fe8984592145b591fc8fb5c6d43190334ba19" }, "mac" : "2103ac29920d71da29f15d75b4a16dbe95cfd7ff8faea1056c33131d846e3097" }, "id" : "3198bc9c-6672-5ab3-d995-4942343ae5b6", "version" : 3 }
一个有许多神奇的参数的粗笨的 JSON 文件,彷佛与复杂的加密操做相关。这毫不吸引人。
若是你看这个 keystore 文件的结构,你会看到大部份内容都是在“crypto”中的:
"crypto" : { "cipher" : "aes-128-ctr", "cipherparams" : { "iv" : "83dbcc02d8ccb40e466191a123791e0e" }, "ciphertext" : "d172bf743a674da9cdad04534d56926ef8358534d458fffccd4e6ad2fbde479c", "kdf" : "scrypt", "kdfparams" : { "dklen" : 32, "n" : 262144, "r" : 1, "p" : 8, "salt" : "ab0c7876052600dd703518d6fc3fe8984592145b591fc8fb5c6d43190334ba19" }, "mac" : "2103ac29920d71da29f15d75b4a16dbe95cfd7ff8faea1056c33131d846e3097" },
这包括:
让咱们看看他们是如何协同工做的,如何在你的密码下保护 keystore 文件。
就像以前提到的,一个以太坊帐户就是用于加密签署交易的一个私钥 —公钥对。为了确保你的私钥没有在文件中明文存储(即任何人只要能获得这个文件就能读),使用强对称算法(cipher)对其加密相当重要。
这些对称算法使用密钥来加密数据。加密后的数据可使用相同的方法和一样的密钥来解密,所以算法命名为对称算法。在本文中,咱们称这个对称密钥为解密密钥,由于它将用于对咱们的以太坊私钥进行解密。
如下是 cipher,cipherparams 和 ciphertext 对应的概念:
因此,在这里,你已经有了进行解密以太坊私钥计算所须要的一切...等等。你须要首先取回你的解密密钥。
-ciphertex 密文的对称解密-
要确保解锁你的帐户很容易,你不须要记住你的每个又长又非用户友好型的用于解密 ciphertext 密文解密密钥。相反,以太坊开发者选择了基于密码的保护,也就是说你只须要输入密码就能拿回解密密钥。
为了能作到这一点,以太坊用了一个密钥生成函数,输入密码和一系列参数就能计算解密密钥。
这就是 kdf 和 kdfparams 的用途:
在这里,用 kdfparams 参数对 scrypt 函数进行调整,反馈到咱们的密码中,你就会获得解密密钥也就是密钥生成函数的输出。
-用密码生成密钥-
咱们描述了用密码和 keystore 文件生成以太坊私钥所须要的全部东西。然而,若是解锁帐户的密码错误会发生什么?
根据迄今为止咱们所看到的,全部操做(密码派生和解密)都会成功,可是最终计算的以太坊私钥不是正确的,这首先违背了密钥文件的使用初衷!
咱们要保证输入解锁帐户的密码是正确的,和最初建立 keystore 文件时同样(回想一下 geth 下建立新帐户时两次输入的密码)。
这就是 keystore 文件中 mac 值起做用的地方。在密钥生成函数执行以后,它的输出(解密密钥)和 ciphertext 密文就被处理【注1】,而且和 mac(就像一种承认的印章)做比较。若是结果和 mac 相同,那么密码就是正确的,而且解密就能够开始了。
【注1】这里有点简略了。在和 mac 进行比较以前,解密密钥(左起第二字节开始的16字节)要和 ciphertext 密文链接在一块儿,并进行哈希散列(用SHA3-256的方法)。 更多信息请访问这里。
唷! 若是你已经作到了这一点,那么恭喜你! 🎉🎊
让咱们回顾一下咱们描述的3个函数。
首先,你输入了密码,这个密码做为 kdf 密钥生成函数的输入,来计算解密密钥。而后,刚刚计算出的解密密钥和 ciphertext 密文链接并进行处理,和 mac 比较来确保密码是正确的。最后,经过 cipher 对称函数用解密密钥对 ciphertext 密文解密。
瞧!解密的结果是你的以太坊私钥。 你能够在这里看看整个过程:
就像你从图中能够看到的,整个过程能够看作一个黑盒(不过,图中是个灰盒),你的密码是唯一的输入,你的以太坊私钥是唯一的输出。所需的其余信息均可以在你的以太坊帐户建立时生成的keystore文件中得到。
因为这个缘由,请确保你的密码足够强(而且不管如何你要记住它!)才能保证即便攻击者偷到了你的keystore文件也不能轻易获得你的私钥。