本文仅供专业人士阅读。
如何工业化地生产私钥与对应地址,然后还可以让用户放心只有自己才掌握着私钥?
为什么会有这样的问题?
我们知道,工业化生产的物理形式的密码学数字资产,是需要把地址和私钥印刷在上面的,这个过程由工厂来实施。
但是,由谁生成私钥?
Ballet是一家生产密码学数字资产物理wallet的公司,他家有一个产品系列叫Ballet REAL,面向小白用户,尽管厂商一再强调不会泄漏私钥(中美两地生产,具体见脚注1),但对于专业人士而言,还是希望私钥由自己生成。
Ballet随后推出了面向专业人士的Ballet Pro,这次允许专业用户自己生成和保管口令(即passphrase),然后自行生成符合BIP38标准(见脚注2)的中间码,用户把中间码写在订单的备注里,然后由厂家生产。(Ballet Pro具体信息见https://www.balletcrypto.com/cn/pro)
这样就能保证安全了?
本文正是要解答这一问题。
一、感性认识
首先来看看中间码的生成过程。
你需要自己先确定一个passphrase(自己掌握,注意保密),当然它要有一定的长度,至少不容易被黑客猜到。
然后使用Ballet给出的页面(见脚注3),生成中间码,如下图:
利用passphrase生成中间码的页面
然后将中间码放在订单备注里就可以了。
这个过程建议离线生成,主要是防止有黑客获取到你的passphrase的键盘记录。
如何离线生成中间码?
可以将Ballet的这个网页保存下来,也即另存为Ballet - Cryptocurrency Wallet.html,然后用U盘拷贝到一个干净的、断网的机器上运行。
如何做一个干净的机器?参考此文:如何在一台旧电脑上安装一个Linux操作系统?
中间码是一个类似中间公钥的东西,厂家拿到这个可以生产最终公钥,但在密码学上保障无法得到最终私钥。
拿到卡后,使用口令passphrase解密EPK
(也即卡片上被贴纸覆盖的部分
),可以计算得到最终私钥。
由于只有用户知道passphrase,所以只有用户能得到最终私钥。
二、基本原理
这个过程是遵循BIP38的。
简单地说,就是:
1、用户用口令产生秘密a,厂家产生秘密b,两个秘密都具备才能做出私钥(即a*b)。
2、用户把a做密码学变换,以中间码的形式给厂家,厂家拿到这个中间码,再结合b,可以得到最终公钥。从密码学上可以保证,厂家不能通过中间码得到a,因而最终算不出私钥。
3、厂家把b加密后生成EPK,印刷在卡片上并密封起来。用户可以通过口令解密EPK得到b,所以用户最终能得到私钥。
秘密即secret,了解密码学的同学都知道的。或者可以简单地看作是密钥(key)。
前面说过,你把中间码给Ballet,Ballet就会做出卡片给你,上面有私钥和地址。
这是Ballet Pro的样子:
Ballet Pro 卡片
可以看到,右上方那个二维码对应的就是地址。
贴纸上面印刷的是地址,贴纸下面是EPK(里面是加密后的b)。
卡片下方那个“cfrm38”开头的75个字符就是确认码(confirmation code),
用户可以用确认码验证此卡片是不是用自己的中间码生成的。
确认码的确认过程仍然在Ballet给出的页面上完成:
验证确认码和解密私钥的页面
确认码是什么概念?
其实就是在不需动用b的情况下,看公钥是否由用户提供的口令产生的。
三、进一步了解BIP38
这需要再稍微深入一些了解BIP38。
说的稍微具体一点,就是:
1、用户用口令passphrase产生秘密a,然后把G*a(中间公钥)发给厂家(这个东西倒推不出秘密a)。
2、厂家产生秘密b,并可计算得出最终公钥G*a*b,而最终私钥就是a*b。但用G*a*b倒推不出a和b。也就是说,厂家只能算出公钥,算不出私钥。
3、厂家用G*a算出一个对称密钥,然后加密b,放在EPK里。厂家又计算G*b,加密后放在确认码里。
4、把地址、确认码等都打印在卡上,把EPK封在贴纸内。
5、用户在校验确认码的时候,用passphrase把G*b解出来,然后计算G*b*a得到公钥,算出地址,看看和地址是不是一致,一致则通过。
6、用户在使用私钥的时候,通过G*a计算ek,然后解密EPK得到秘密b。用户得到私钥a*b。
中间码里面的主要信息是G*a,可以简单理解为a的公钥,所以这个信息可以公开。
确认码里面的主要信息就是G*b,可以简单理解为b的公钥,所以这个信息可以公开。
确认码里面的G*b是用passphrase信息加密过的,目的是让用户确认一下没有差错。
现在你应该就基本明白BIP38是怎么回事了,如果还想深入了解,看下面这节。
四、深入了解BIP38
用户生成中间码:
1、用户用程序生成8字节的随机数ownerentropy(其实就是盐),如果需要,其中可以加上批次号和序列号。
2、使用scrypt算法,用passphrase做口令,用owenersalt做salt,生成32字节的passfactor。
3、计算G*passfactor,得到passpoint。(这个passfactor就是上面说的a
)
4、将ownerentropy和passpoint连接起来后编码,得到一个以“passphrase”开头的72字节长度的字符串,这就是“中间码”。把这个给厂家。(主要内容是passpoint,即用户侧中间公钥)
厂商制作卡片:
5、厂商拿到中间码后,开始着手生成地址和EPK。
6、首先是生成24字节的随机数seedb,然后两次SHA256后,得到32字节的factorb。(这个factorb就是上面说的b
)
7、计算passpoint*factorb,其结果就是公钥,然后可以生成地址(印在卡片上),然后通过hash生成4字节的addrhash。
8、使用scrypt算法,passpoint为口令,ownerentropy+addrhash为salt,生成用来加密seeb的ek。
9、使用AES256算法,用ek对seeb加密,得到加密后的seeb,简称eseedb。
10、将addrhash、ownerentropy、eseedb连接起来,编码后,得到一个以“6P”开头的EPK,印在卡片上。里面最重要的内容是加密后的seeb。
厂商生成确认码:
11、计算G*factorb,得到pointb,然后用上面第8步passpoint产生的ek加密pointb得到epointb。
12、将addhash、ownerentropy、epointb连接,编码后 ,得到以"cfrm38”开头的75字节的字符串。这就是“确认码”。*
13、厂商将此“确认码”打印在卡片上。(里面最重要的内容是加密后的厂商侧中间公钥)
用户验证确认码:
14、用户在验证程序中输入自己的passphrase,程序从确认码中获取ownerentropy、addrhash,然后用scrypt算法,可以得到上面第8步的ek。
15、用ek解密出pointb,然后计算poinb*passfactor,得到公钥,然后可以得到地址。
16、验证程序显示:“It is confirmed that Bitcoin address address depends on this passphrase”。用户得以放心。
用户计算私钥:
17、用户在应用程序中输入自己的passphrase;并通过扫码得到EPK。
18、用户从EPK中拿到ownerentropy,然后结合passphrase,使用scrypt算法,算出passfactor、算出passpoint。
19、用户使用addrhash、ownerentropy,可以生成ek,然后从EPK中把eseedb提取出来并用ek解密,得到seedb。
20、用seedb计算出factorb,然后计算出passfactor*factorb,这就是私钥。
21、用私钥计算公钥,然后得到地址,验证addrhash是否正确,正确就表明一切正确,否则就说明passphrase不对。
如果还想更深入的了解,或者你想自己做一个BIP38的实现,你就只能去看BIP38原文了[1]。
五、后记
现在回想一下Ballet Real系列,结合文献2可以得知,Ballet美国总部在离线计算机上所做的事,正是专业人士要做的事,也即公司替用户生成了passphrase、批次号并生成了中间码,然后这个中间码发送到中国办公室,生成地址和EPK,再将卡片(连同确认码)送往美国,将passphrase蚀刻到卡片上并用防伪涂层覆盖。而那个验证码,应该就是addrhash产生的。
Ballet Real卡片
在Pro系列中,原先由美国总部完成的事,现在由专业玩家自己来做了。
此外,Ballet Pro还做出了一项重大革新,就是卡片一式三份,三张卡片一摸一样(只是序号后缀区别为abc),这使得备份变得容易,不像REAL系列需要自己再想办法备份。
说实话,我还没有见过这种专门给专业人士玩的工业化产品。
什么专业?密码学?不,区块链工程。
我国新增区块链工程专业(专业代码080917T)
— END —
注:封面图片来自《星际探索》
关注本公众号查看区块链系列文章
本文分享自微信公众号 - 微月人话(man-mind)。
如有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。