zoukankan      html  css  js  c++  java
  • geth中UTC文件与私钥的关系

    在创建了自己的本地区块链后,我们会得到一个文件夹keystore,该文件夹是用来存储你在这个区块链中创建的账户的备份钥匙文件,比如在这里我有一个账户的备份钥匙文件为:UTC--2018-07-12T06-48-30.819494813Z--91b678137f09c8b4f294a14e88c09276522618cf(json文件)

    {"address":"91b678137f09c8b4f294a14e88c09276522618cf",
      "crypto":{
        "cipher":"aes-128-ctr",
        "ciphertext":"ebd32eef42c403fbe6509a8b5ae5b2d7d4eb15ee1a046ae23c3383ad672f0fcd",
        "cipherparams":{
          "iv":"0406c84c7a744beb6774214f912327dd"
        
    },
        "kdf":"scrypt",
        "kdfparams":{
          "dklen":32,
          "n":262144,
          "p":1,
          "r":8,
          "salt":"260bebdb9cb810a63d1060f69ebd35a479c77d5fd11a16fb496367359cb99f2a"
        },
        "mac":"5bb1d0ea80da66265f044f075f5fcf7c736500c75fa1a0d5d52e25f9bceea7a2"
      },
    "id":"fa03979a-f607-4de9-b32a-4952cc93ca6f",
    "version":3
    }
    cipher:加密算法,对称加密,AES算法,用于加密以太坊私钥;
    
    cipherparams:cipher算法需要的参数,参数iv,是aes-128-ctr加密算法需要的初始化向量;
    
    ciphertext:私钥加密后的密文,你的以太坊私钥使用上述 cipher 算法进行加密,这样你的私钥不会是明文存储,aes-128-ctr函数的解密输入密文;
    //所以将ciphertext的密文解密密钥、ciphertext加密后的私钥、cipherparams算法所需的参数 这三者输入到对称算法aes-128-ctr中后,就能够得到私钥了
    //然后从上面所需的三个输入中我们就知道我们现在还不知道ciphertext的密文解密密钥是什么,那么下面就是用于生成这个解密的
    kdf:秘钥生成函数,用于使用你自己设置的密码加密keystore文件,所以你要用自己的密码解密keystore文件后才能得到私钥 //用 kdfparams 参数对 scrypt 函数进行调整 kdfparams:kdf算法所需要的参数;
    //kdfkdfparams的作用就是生成ciphertext的密文解密密钥,因为我们很难记得这个长串的密钥,所以在这里我们只需要通过这个密钥生成函数scrypt、其参数kdfparams以及自己设置的密码password
    //这三者我们就能够得到ciphertext的密文解密密钥,然后将其输入到上面的aes-128-ctr加密算法用于解密ciphertext,我们就能够得到自己的私钥了


    //mac的作用是用做一开始输入密码password的时候来判断输入的这个密码是不是正确的,正确的才开始上面解密ciphertext的过程
    //就是我们先通过输入的密码、密钥生成函数scrypt及其参数kdfparams三者得到密文解密密钥
    //然后使用其左起第二个字节开始的16个字节以及ciphertext连接在一起,并进行哈希散列(用SHA3-256的方法)
    //然后将得到的值hash与mac的值做比对,相同才说明输入的密码为该账户设置的密码,mac也是根据上面的步骤得到的

    mac:验证密码的编码;

    Remarks about toV3

    The options is an optional object hash, where all the serialization parameters can be fine tuned:

    • uuid - UUID. One is randomly generated.随机生成
    • salt - Random salt for the kdf. Size must match the requirements of the KDF (key derivation function). Random number generated via crypto.getRandomBytes if nothing is supplied.kdf的随机salt。大小必须符合KDF(key派生函数)的要求。通过密码生成的随机数。如果没有提供任何内容,则为getRandomBytes。
    • iv - Initialization vector for the cipher. Size must match the requirements of the cipher. Random number generated via crypto.getRandomBytes if nothing is supplied.密码的初始化向量。大小必须符合密码的要求。通过密码生成的随机数。如果没有提供任何内容,则为getRandomBytes。
    • kdf - The key derivation function, see below.key的推导函数
    • dklen - Derived key length. For certain cipher settings, this must match the block sizes of those.派生key的长度,对于某些密码设置,这必须与这些设置的块大小匹配
    • cipher - The cipher to use. Names must match those of supported by OpenSSL, e.g. aes-128-ctr or aes-128-cbc.使用密码。名称必须与OpenSSL支持的名称匹配,例如aes-128-ctr或aes-128-cbc。

    Depending on the kdf selected, the following options are available too.

    For pbkdf2:

    • c - Number of iterations. Defaults to 262144.迭代次数
    • prf - The only supported (and default) value is hmac-sha256. So no point changing it.唯一支持的(也是默认的)值是hmac_sha256。所以没有必要改变它。

    For scrypt:

    • n - Iteration count. Defaults to 262144.迭代次数
    • r - Block size for the underlying hash. Defaults to 8.底层哈希的块大小。默认为8。
    • p - Parallelization factor. Defaults to 1.并行化的因素。默认为1。

    The following settings are favoured by the Go Ethereum implementation and we default to the same:

    下面的设置是Go Ethereum实现支持的,我们默认的设置也是如此

    • kdf: scrypt
    • dklen: 32
    • n: 262144
    • r: 8
    • p: 1
    • cipher: aes-128-ctr

    所以我们总结上面的过程,我们就知道该钥匙文件的使用过程为:

    首先,你输入了密码password,这个密码将作为 kdf 密钥生成函数的输入,来计算密文解密密钥

    然后,将密文解密密钥 ciphertext 密文连接并进行处理,和 mac 比较来确保密码是正确的。

    最后,通过 cipher 对称函数用密文解密密钥 ciphertext 密文解密,得到私钥

    钥匙文件的文件名格式为UTC。账号列出时是按字母顺序排列,但是由于时间戳格式,实际上它是按创建顺序排列。

    所以,在整个过程中你的密码是惟一的输入,你的以太坊私钥是惟一的输出。所需的其他信息都可以在你的以太坊账户创建时生成的keystore文件中获得。

    所以一定要确保你的密码足够强,这样能保证即使有人得到了你的keystore文件,它也无法获得你的私钥。

     想了解scrypt可看:

    https://tools.ietf.org/html/rfc7914

    https://zhuanlan.zhihu.com/p/32484253

    私钥、公钥、地址之间的关系:

    每个账户都由一对密钥来定义,包括公钥和私钥。我们通过自己设置的密码以及钥匙备份文件UTC--...能够得到自己账户的私钥,私钥通过一系列运算后能够得到公钥

    比如比特币系统使用了椭圆曲线签名算法,通过私钥可以计算出公钥:

                  Hash(Hash(ECC(私钥)))  -> 公钥

    要想反向从公钥得到私钥是十分困难的

    在以太坊中取公钥的最后20个字节作为地址

    所以,一定要将钥匙备份文件备份保存,并且要牢记你自己的密码,如果你丢失了钥匙备份文件或者忘记了密码,那么你的币将丢失,密码是无法找回的。

  • 相关阅读:
    多层开发的小知识
    DIV+CSS基础教程:导航条的制作详解
    JavaScript函数
    css:学习CSS了解单位em和px的区别
    blank开新窗口为什么通不过W3C验证
    对javascript匿名函数的理解(透彻版)
    .net如何与windows身份验证的sql数据库连接
    Aptana2.0系列教程
    C# Tostring() 格式大全
    类关系图
  • 原文地址:https://www.cnblogs.com/wanghui-garcia/p/9522642.html
Copyright © 2011-2022 走看看