主页 > imtokenios版下载 > 什么是以太坊私钥存储(Keystore)文件?
什么是以太坊私钥存储(Keystore)文件?
访问密钥库以管理以太坊私钥的门槛很高,主要是因为以太坊客户端将大部分加密复杂性隐藏在简单的命令行或图形界面下。
例如,对于 geth:
$ geth 新账户
您的新帐户已使用密码锁定。
请给个密码。 不要忘记这个密码。
密码: 重复密码:
地址:{008aeeda4d805471df9b2a5b0f38a0c3bcba786b}
$ geth 帐户列表帐户 #0:{8a1c4d573cc29a96547816522cfe0b266e88abac} 密钥库:~/.ethereum/keystore/UTC---- 008aeeda4d805471df9b2a5b0f38a0c3bcba786b
我只需要输入 3 个词来创建一个新帐户。 然后输入两次密码,就这么简单! 我的以太坊密钥库文件已创建。 您需要将那些非常珍贵的密钥库文件备份并存储在一个或多个隐藏位置,以便只有您可以访问它们并访问资金。 从经验来看,当我不完全理解一个新概念的精妙之处,并过度依赖抽象层和现有工具来让我的生活更轻松时,我很可能会忘记事情,采取不必要的捷径并将其搞砸向上。 如果搞砸了有余额的以太坊私钥,它最终可能会永远锁定我辛苦赚来的以太币(谢天谢地,这还没有发生!)。 幸运的是,作为一个以太坊用户,没有多少方法可以让你搞砸:你丢失了你的密钥库文件,你忘记了与该文件关联的密码,或者两者兼而有之,你就搞砸了。
在本文中,我们将向您介绍如何从密钥库文件中计算出以太坊私钥。 我们将讨论密码函数(对称加密、密钥生成函数、SHA3 哈希算法),但我们会尽量使解释尽可能简洁直接。
什么是密钥库文件?
以太坊密钥库文件(在 Linux 系统上存储在 ~/.ethereum/keystore 或在 Windows 系统上存储在 C:\Users\Appdata/Roaming/Ethereum/keystore 中)是您用于签署交易的唯一以太坊私钥。 加密文件。 如果你丢失了这个文件,你就丢失了你的私钥,这意味着你失去了签署交易的能力,这意味着你的资金被永久锁定在你的账户中。 当然,你可以直接将你的以太坊私钥存储在一个加密文件中,但是你的私钥很容易受到攻击,攻击者只需读取你的文件,使用你的私钥签署交易,然后将资金转入他们的账户。 在您意识到发生了什么之前,您的硬币会在短时间内丢失。 这就是创建以太坊密钥库文件的原因:它允许您存储加密的密钥。 这是安全性(攻击者需要密钥库文件和您的密码来窃取您的资金)和可用性(您只需要密钥库文件和密码来花钱)之间的完美平衡。 为了让你发送一些以太币,大多数以太坊客户端会要求你输入密码(与你创建帐户时使用的密码相同)来解密你的以太坊私钥。 解密后,客户端程序将获得私钥来签署交易,从而允许您转移资金。
密钥库文件是什么样的?
如果您打开其中一个帐户文件,它看起来像这样(取自此处):
$ cat ~/.ethereum/keystore/UTC----008aeeda4d805471df9b2a5b0f38a0c3bcba786b
{ “加密货币”:
{
“密码”:“aes-128-ctr”,
“密码参数”:{
“四”:“83dbcc02d8ccb40e466191a123791e0e”},
“密文”:“d172bf743a674da9cdad04534d56926ef8358534d458fffccd4e6ad2fbde479c”,
“kdf”:“scrypt”,
“kdfparams”:{
“dklen”:32,
“n”:262144,
“r”:1,
“p”:8,
“盐”:“ab0c7876052600dd703518d6fc3fe8984592145b591fc8fb5c6d43190334ba19”
},
“mac”:“2103ac29920d71da29f15d75b4a16dbe95cfd7ff8faea1056c33131d846e3097”
},
“编号”:“3198bc9c-6672-5ab3-d995-4942343ae5b6”,
“版本”:3
}
一个笨重的 JSON 文件,其中包含许多似乎与复杂的加密操作相关的神奇参数。 这绝不是吸引人的。 让我们再深入一点。 如果您查看此密钥库文件的结构,您会发现大部分内容都在“crypto”中:
“加密货币”:{
“密码”:“aes-128-ctr”,
“密码参数”:{
“四”:“83dbcc02d8ccb40e466191a123791e0e”
},
“密文”:“d172bf743a674da9cdad04534d56926ef8358534d458fffccd4e6ad2fbde479c”,
“kdf”:“scrypt”,
“kdfparams”:{
“dklen”:32,
“n”:262144,
“r”:1,
“p”:8,
“盐”:“ab0c7876052600dd703518d6fc3fe8984592145b591fc8fb5c6d43190334ba19”
},
“mac”:“2103ac29920d71da29f15d75b4a16dbe95cfd7ff8faea1056c33131d846e3097”
},
这包括:
cipher:对称AES算法的名称;
cipherparams:上述密码算法需要的参数;
密文:您的以太坊私钥是使用上述密码算法加密的;
kdf:密钥生成函数,用来让你用密码加密keystore文件;
kdfparams:上述kdf算法需要的参数;
Mac:用于验证密码的代码。
让我们看看它们如何协同工作以使用您的密码保护密钥库文件。
加密你的私钥
如前所述,以太坊账户是用于对交易进行加密签名的私钥-公钥对。 为了保证你的私钥不明文存储在文件中(即任何能拿到文件的人都能读取),用强对称算法(cipher)加密是必不可少的。 这些对称算法使用密钥来加密数据。 加密数据可以用相同的方法和相同的密钥解密,因此该算法被命名为对称算法。 在本文中,我们将此对称密钥称为解密密钥,因为它将用于解密我们的以太坊私钥。
以下是cipher、cipherparams、ciphertext对应的概念:
Cipher是一种对称加密算法,用于加密以太坊私钥。这里cipher采用aes-128-ctr加密方式
Cipherparams是aes-128-ctr加密算法需要的参数。
在这里,唯一使用的参数 iv 是 aes-128-ctr 加密算法所需的初始化向量。
密文是 aes-128-ctr 函数的加密输入。
因此,在这里,您拥有了进行计算以解密以太坊私钥等所需的一切。 您需要先检索您的解密密钥。
1 -ciphertex密文的对称解密-
2. 用密码保护它
为确保轻松解锁您的帐户,您无需记住用于解密密文的每一个又长又不友好的解密密钥。 相反,以太坊开发人员选择了基于密码的保护,这意味着您只需输入密码即可取回解密密钥。
为了做到这一点,以太坊使用了密钥生成函数,可以通过输入密码和一系列参数来计算解密密钥。 这就是 kdf 和 kdfparams 的用途:
kdf 是一种密钥生成函数,可根据您的密码计算(或检索)解密密钥。 这里kdf使用了scrypt算法。
kdfparams 是 scrypt 函数需要的参数。 在这里,简单地说,dklen、n、r、p 和 salt 是 kdf 函数的参数。
可以在此处找到有关 scrypt 函数的更多信息。 在这里,使用 kdfparams 参数调整 scrypt 函数,将其输入我们的密码,您将获得解密密钥,这是密钥生成函数的输出。
2 - 使用密码生成密钥 -
3.确保您的密码正确
我们描述了从密码短语和密钥库文件生成以太坊私钥所需的一切。 但是,如果解锁账户的密码错误怎么办?
就我们目前所看到的,所有操作(密码推导和解密)都会成功,但是最终计算出的以太坊私钥是不正确的,这违背了使用密钥文件的初衷!
我们需要确保解锁账户时输入的密码是正确的,与最初创建keystore文件时的密码一致(回想一下在geth下新建账户时输入的两次密码)。 这是密钥库文件中的 mac 值发挥作用的地方。 执行密钥生成函数后,对其输出(解密密钥)和密文进行处理[注1],并与mac进行比较(类似一种认可印章)。 如果结果与mac相同,则密码正确,即可开始解密。
[注1] 这里稍微简述一下。 在与mac比较之前,将解密密钥(从左起第二个字节开始的16字节)与密文密文拼接起来并进行哈希处理(使用SHA3-256方法)。 欲了解更多信息,请访问此处。
把它们放在一起想想吧!
如果你已经做到了这一步,那么恭喜你! 让我们回顾一下我们描述的 3 个函数。
首先,您输入密码,该密码用作 kdf 密钥生成函数的输入,用于计算解密密钥。
然后,将刚刚计算出的解密密钥与密文进行拼接处理,并与mac进行比较,确保密文正确。
最后用解密密钥通过密文对称函数对密文密文进行解密。 看! 解密的结果就是你的以太坊私钥。
你可以在这里看到整个过程:
从图中可以看出,整个过程可以看成一个黑框(不过图中是灰色框),你的密码是唯一的输入,你的以太坊私钥是唯一的输出。 所需的所有其他信息都可以在创建以太坊帐户时生成的密钥库文件中找到。 因此,请确保您的密码足够强(并且您无论如何都要记住它!),这样即使攻击者窃取了您的密钥库文件,也无法轻易获得您的私钥。
测试数据
细节:
地址:008aeeda4d805471df9b2a5b0f38a0c3bcba786b
ICAP:XE542A5PZHH8PYIZUBEJEO0MFWRAPPIL67
UUID: 3198bc9c-6672-5ab3-d9954942343ae5b6
密码:测试密码
秘密:7a28b5ba57c53603b0b07b56bba752f7784bf506fa95edc395f5cf6c7514fe9d
PBKDF2-SHA-256
使用 AES-128-CTR 和 PBKDF2-SHA-256 的测试向量:
~/.web3/keystore/3198bc9c-6672-5ab3-d9954942343ae5b6.json 的文件内容:
{
“加密货币”:{
“密码”:“aes-128-ctr”,
“密码参数”:{
“四”:“6087dab2f9fdbbfaddc31a909735c1e6”
},
“密文”:“5318b4d5bcd28de64ee5559e671353e16f075ecae9f99c7a79a38af5f869aa46”有余额的以太坊私钥,
“kdf”:“pbkdf2”,
“kdfparams”:{
“c”:262144,
“dklen”:32,
“prf”:“hmac-sha256”,
“盐”:“ae3cd4e7013836a3df6bd7241b12db061dbe2c6785853cce422d148a624ce0bd”
},
“mac”:“517ead924a9d0dc3124507e3393d175ce3ff7c1e96529c6c555ce9e51205e9b2”
},
“编号”:“3198bc9c-6672-5ab3-d995-4942343ae5b6”,
“版本”:3
}
中间体:
派生密钥:f06d69cdc7da0faffb1008270bca38f5e31891a3a773950e6d0fea48a7188551
MAC 主体:e31891a3a773950e6d0fea48a71885515318b4d5bcd28de64ee5559e671353e16f075ecae9f99c7a79a38af5f869aa46
MAC517ead924a9d0dc3124507e3393d175ce3ff7c1e96529c6c555ce9e51205e9b2
密钥:f06d69cdc7da0faffb1008270bca38f5
密码
使用 AES-128-CTR 和 Scrypt 的测试向量:
{
“加密货币”:{
“密码”:“aes-128-ctr”,
“密码参数”:{
“四”:“83dbcc02d8ccb40e466191a123791e0e”
},
“密文”:“d172bf743a674da9cdad04534d56926ef8358534d458fffccd4e6ad2fbde479c”,
“kdf”:“scrypt”,
“kdfparams”:{
“dklen”:32,
“n”:262144,
“r”:1,
“p”:8,
“盐”:“ab0c7876052600dd703518d6fc3fe8984592145b591fc8fb5c6d43190334ba19”
},
“mac”:“2103ac29920d71da29f15d75b4a16dbe95cfd7ff8faea1056c33131d846e3097”
},
“编号”:“3198bc9c-6672-5ab3-d995-4942343ae5b6”,
“版本”:3
}
中间体:
派生密钥:fac192ceb5fd772906bea3e118a69e8bbb5cc24229e20d8766fd298291bba6bd
MAC Bodybb5cc24229e20d8766fd298291bba6bdd172bf743a674da9cdad04534d56926ef8358534d458fffccd4e6ad2fbde479c
MAC: 2103ac29920d71da29f15d75b4a16dbe95cfd7ff8faea1056c33131d846e3097
密钥:fac192ceb5fd772906bea3e118a69e8b
从密钥库中提取私钥的源代码
包主
进口 (
“编码/十六进制” “标志” “fmt” “io/ioutil” “os” “github.com/ethereum/go-ethereum/accounts/keystore” “github.com/ethereum/go-ethereum/crypto”)
功能主要(){
ksfilefullpath := ""kstype := ""kspassword := ""flags := flag.NewFlagSet(os.Args[0], flag.ExitOnError)
flags.StringVar(&ksfilefullpath, "keystore-src", "", "要处理的密钥库的路径")
flags.StringVar(&kstype, "keystore-type", "", "keystore type: `pem`, `keystore`")
旗帜。 StringVar(&kspassword, "keystore-password", "", "keystore-password")
如果错误 := flags.Parse(os.Args[1:]); 错误!=无{
fmt.Fprintln(os.Stderr, "解析标志失败:", err)
操作系统。 出口(1)
}
keyjson,错误:= ioutil.ReadFile(ksfilefullpath)
如果错误!=无{
fmt.Println(错误)
}
// 使用正确的密码密钥解密,err := keystore. 解密密钥(keyjson,kspassword)
如果错误!=无{
fmt.Println("test : json key 解密失败: %v", err)
}
fmt.Println("私钥= " + hex.EncodeToString(crypto.FromECDSA(key.PrivateKey)))
}
编译
跑步
提取的私钥:ab979c2c4d092212af817802f31313bd6f4144b4b9cb289f659c29f5cabbd428
开始,上传密钥库
看看结果
呵呵,一模一样