资讯专栏INFORMATION COLUMN

区块链中密钥对的生成原理

jackzou / 3214人阅读

摘要:通过命令行中显示结论压缩形式占据一个或的前缀的坐标从代码中生成注原文作者的密钥对的产生过程是冗长的,然而使用来完成却不难。可以是一个完整的密钥对或者是一个多带带的公钥。

bitcoin中的密钥综述

关于bitcon中使用的椭圆曲线加密体制的一些事实:

私钥长度 32bytes

公钥长度 64bytes (未压缩形式) 或者 32bytes(压缩形式)+ 1byte(前缀)

椭圆曲线Csecp256k1曲线

椭圆曲线加密体制基于模运算

在本文中,我们唯一的输入就是私钥。公钥可以唯一地从私钥推导而来。我们先使用openssl命令行生成一个密钥对样例,然后再尝试编写C语言代码进行同样的操作。

在OpenSSL命令行中生成 私钥

一个私钥是一个随机选取的32 bytes的数字,并且我们都知道32 bytes存储的数字可以转换成为一个非常大的数值,最大可以达到2256。去猜测这样一个数字是很荒谬的,因此可以认为它的生成具有很高的随机性。

得到一个全新的私钥是非常容易的:

$ openssl ecparam -name secp256k1 -genkey -out ec-priv.pem

生成的结果文件ec-prive.pem中包含了曲线名称(secp256k1)和私钥,它们连同一些其它字符一起被base64编码。

这个文件可以被快速解码为可读的16进制形式:

openssl ec -in ec-priv.pem -text -noout

以下是我所生成的密钥对形式(你生成的与我的不相同):

read EC key
Private-Key: (256 bit)
priv:
    16:26:07:83:e4:0b:16:73:16:73:62:2a:c8:a5:b0:
    45:fc:3e:a4:af:70:f7:27:f3:f9:e9:2b:dd:3a:1d:
    dc:42
pub: 
    04:82:00:6e:93:98:a6:98:6e:da:61:fe:91:67:4c:
    3a:10:8c:39:94:75:bf:1e:73:8f:19:df:c2:db:11:
    db:1d:28:13:0c:6b:3b:28:ae:f9:a9:c7:e7:14:3d:
    ac:6c:f1:2c:09:b8:44:4d:b6:16:79:ab:b1:d8:6f:
    85:c0:38:a5:8c
ASN1 OID: secp256k1

其中私钥被显示为这样的形式会更直观:

16 26 07 83 e4 0b 16 73
16 73 62 2a c8 a5 b0 45
fc 3e a4 af 70 f7 27 f3
f9 e9 2b dd 3a 1d dc 42

这个私钥代表着你的身份,必须安全地将它保存。也就是说,如果这不是我用来举例的而生成的私钥,我不会将它分享给任何人。我们会用这个私钥来签名我们的信息,这样的话所有人就会相信这个信息确实是我本人发出的。如果其他人窃取了你的私钥,他将能够伪造你的身份。在bitcoin中,他就能够拿走你所有的钱。一定要当心!

公钥

默认情况下,一个公钥是由两个 32bytes 的大数组成,这种就是所谓的未压缩形式。这两个数字代表着二维坐标系上,secp256k1椭圆曲线上的一个点(x,y),它是符合以下方程的:

y2 = x3 + 7

这个点的坐标是由私钥决定的,但是反之,从点的坐标推断私钥是不可行的。毕竟,这就是椭圆曲线加密算法安全性的保障。根据依赖特性,结合上述方程和一个x值,可以计算得到一个对应的y值。事实上,压缩形式的公钥就是根据这个原理将y值省略掉来节省空间的。

我们可以将上述密钥对中的公钥部分取出,存储到一个叫做ec-pub.pem的外部文件中:

$ openssl ec -in ec-priv.pem -pubout -out ec-pub.pem

接着将它解码:

$ openssl ec -in ec-pub.pem -pubin -text -noout

未包含私钥部分的文本形式就会显示出来:

read EC key
Private-Key: (256 bit)
pub: 
    04:82:00:6e:93:98:a6:98:6e:da:61:fe:91:67:4c:
    3a:10:8c:39:94:75:bf:1e:73:8f:19:df:c2:db:11:
    db:1d:28:13:0c:6b:3b:28:ae:f9:a9:c7:e7:14:3d:
    ac:6c:f1:2c:09:b8:44:4d:b6:16:79:ab:b1:d8:6f:
    85:c0:38:a5:8c
ASN1 OID: secp256k1

一个更加直观的版本:

04

82 00 6e 93 98 a6 98 6e
da 61 fe 91 67 4c 3a 10
8c 39 94 75 bf 1e 73 8f
19 df c2 db 11 db 1d 28

13 0c 6b 3b 28 ae f9 a9
c7 e7 14 3d ac 6c f1 2c
09 b8 44 4d b6 16 79 ab
b1 d8 6f 85 c0 38 a5 8c

这个未压缩的版本包含了65个字节:

一个不变的04前缀

32 bytes 的 x 坐标

32 bytes 的 y 坐标

很容易就可以将它转换为压缩形式。我们只需省略掉y并改掉它的前缀。这个新前缀是根据y来决定的:前缀是 02表示y是偶数值,前缀是 03表示y是奇数值。

通过:

$ openssl ec -in ec-pub.pem -pubin -text -noout -conv_form compressed

命令行中显示:

read EC key
Private-Key: (256 bit)
pub: 
    02:82:00:6e:93:98:a6:98:6e:da:61:fe:91:67:4c:
    3a:10:8c:39:94:75:bf:1e:73:8f:19:df:c2:db:11:
    db:1d:28
ASN1 OID: secp256k1

结论, 压缩形式占据33bytes:

一个0203 的前缀

32bytes 的 x 坐标

从代码中生成

(注:原文作者的 repository)

密钥对的产生过程是冗长的,然而使用OpenSSL来完成却不难。我ec.h中声明了一个帮助函数,原型如下:

EC_KEY *bbp_ec_new_keypair(const uint8_t *priv_bytes);

我们来一起分析一下原文中的部分代码,一些OpenSSL中的数据结构如下:

BN_CTX, BIGNUM

EC_KEY

EC_GROUP, EC_POINT

前两个结构体属于OpenSSL的任意精度算数(大数)部分,因为我们需要处理非常大的数字。EC_KEY可以是一个完整的密钥对或者是一个多带带的公钥。EC_GROUPEC_POINT帮助我们根据私钥来计算公钥。

最重要的部分,我们初始化了一个EC_KEY结构来存储一对密钥对:

key = EC_KEY_new_by_curve_name(NID_secp256k1);

填充私钥是很容易的,但是需要一个过渡过程。再将要输入的priv_bytes填入密钥对之前,我们需要将它转换为BIGNUM,在这里命名为priv

BN_init(&priv);
BN_bin2bn(priv_bytes, 32, &priv);
EC_KEY_set_private_key(key, &priv);

对于复杂的大数操作,OpenSSL需要一个上下文环境,这就是BN_CTX需要被创建的原因。公钥的推导需要一个深层次的数学理解,而这并不是这篇文章所要达到的目标。简单来说,就是我们在曲线上定位一个固定的点G(generator, 代码中的group), 然后乘以标量私钥n,而这是一个在模运算中不可逆的过程。它的结果P = n * G就是第二个点,公钥pub。最终,公钥被载入到密钥对中:

ctx = BN_CTX_new();
BN_CTX_start(ctx);

group = EC_KEY_get0_group(key);
pub = EC_POINT_new(group);
EC_POINT_mul(group, pub, &priv, NULL, NULL, ctx);
EC_KEY_set_public_key(key, pub);

最后时刻,我们要在ex-ec-keypair.c测试密钥对。我们期待如果给定一个固定的私钥,通过代码产生的结果和命令行中产生的结果相同。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/23967.html

相关文章

  • 区块链之非对称加密算法

    摘要:二如何理解公钥和私钥非对称加密算法需要两个密钥公开密钥和私有密钥。因为加密和解密使用的是两个不同的密钥,所以这种算法叫作非对称加密算法。三非对称加密解密原理非对称加密算法中,常用的就是算法了,以下就以算法为例来讲解非对称加密算法的实现原理。 非对称加密,在现在网络应用中,有这非常广泛的场景,更是加密货币的基础。本文主要介绍非对称加密、解密的原理和过程,以及在区块链中的使用。 一、非对称...

    mcterry 评论0 收藏0
  • 理解开发HD钱包涉及的BIP32、BIP44、BIP39

    摘要:本文首发于深入浅出区块链社区原文链接理解开发钱包涉及的原文已更新,请读者前往原文阅读如果你还在被钱包搞的一头雾水,来看看这边文章吧。所以我们要开发以太坊钱包同样需要对比特币的钱包提案有所了解。 本文首发于深入浅出区块链社区原文链接:理解开发HD钱包涉及的BIP32、BIP44、BIP39原文已更新,请读者前往原文阅读 如果你还在被HD钱包、BIP32、BIP44、BIP39搞的一头雾水...

    firim 评论0 收藏0
  • 理解开发HD钱包涉及的BIP32、BIP44、BIP39

    摘要:本文首发于深入浅出区块链社区原文链接理解开发钱包涉及的原文已更新,请读者前往原文阅读如果你还在被钱包搞的一头雾水,来看看这边文章吧。所以我们要开发以太坊钱包同样需要对比特币的钱包提案有所了解。 本文首发于深入浅出区块链社区原文链接:理解开发HD钱包涉及的BIP32、BIP44、BIP39原文已更新,请读者前往原文阅读 如果你还在被HD钱包、BIP32、BIP44、BIP39搞的一头雾水...

    tianren124 评论0 收藏0
  • 比特币入门笔记

    摘要:也就是说,比特币是一个完全出于社区共识的货币。所谓全称为,它是比特币交易的基本单位。根据比特币的协议,一个区块的大小是而一笔交易大概是,因此一个区块大概可以包含笔交易。 诞生 比特币诞生于 2008 年,一个网名为中本聪的人,提出了一个设想: 创造一种不受政府或任何组织控制的货币 比特币的本质就是一串数字,没有任何资产支持(现行货币背后都是国家或银行提供资产支持)。也就是说,比特币是一...

    Loong_T 评论0 收藏0
  • 通过Python入门区块

    摘要:通过入门区块链本文翻译自的文章原文地址区块链可能是继互联网之后最重大和最具突破性的技术。先不管对比特币和其他加密货币价格的疯狂行情,本文旨在帮助读者入门区块链技术。 通过Python入门区块链 本文翻译自 Adil Moujahid 的文章 A Practical Introduction to Blockchain with Python原文地址:http://adilmoujahi...

    andong777 评论0 收藏0

发表评论

0条评论

jackzou

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<