比原怎么通过create-key接口创建密钥

免费建站   2024年05月10日 10:51  

这篇文章主要讲解了“比原怎么通过create-key接口创建密钥”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“比原怎么通过create-key接口创建密钥”吧!

在API.buildHandler方法中:

api/api.go#L164-L244

func(a*API)buildHandler(){//...ifa.wallet!=nil{//...m.Handle("/-",jsonHandler(a.pseudohsmCreateKey))//...

可见,其路径为/create-key,而相应的handler是a.pseudohsmCreateKey(外面套着的jsonHandler在之前已经讨论过,这里不提):

api/hsm.go#L23-L32

func(a*API)pseudohsmCreateKey(ctxcontext.Context,instruct{Aliasstring`json:"alias"`Passwordstring`json:"password"`})Response{xpub,err:=a.wallet.Hsm.XCreate(in.Alias,in.Password)iferr!=nil{returnNewErrorResponse(err)}returnNewSuccessResponse(xpub)}

它主要是调用了a.wallet.Hsm.XCreate,让我们跟进去:

blockchain/pseudohsm/pseudohsm.go#L50-L66

//XCreateproducesanewrandomxprvandstoresitinthedb.func(h*HSM)XCreate(aliasstring,authstring)(*XPub,error){//...//1.normalizedAlias:=strings.ToLower(strings.TrimSpace(alias))//2.ifok:=h.cache.hasAlias(normalizedAlias);ok{returnnil,ErrDuplicateKeyAlias}//3.xpub,_,err:=h.createChainKDKey(auth,normalizedAlias,false)iferr!=nil{returnnil,err}//4.h.cache.add(*xpub)returnxpub,err}

其中出现了HSM这个词,它是指Hardware-Security-Module,原来比原还预留了跟硬件相关的模块(暂不讨论)。

上面的代码分成了4部分,分别是:

首先对传进来的alias参数进行标准化操作,即去两边空白,并且转换成小写

检查cache中有没有,有的话就直接返回并报个相应的错,不会重复生成,因为私钥和别名是一一对应的。在前端可以根据这个错误提醒用户检查或者换一个新的别名。

调用createChainKDKey生成相应的密钥,并拿到返回的公钥xpub

把公钥放入cache中。看起来公钥和别名并不是同一个东西,那前面为什么可以查询alias呢?

所以我们进入h.cache.hasAlias看看:

blockchain/pseudohsm/keycache.go#L76-L84

func(kc*keyCache)hasAlias(aliasstring)bool{xpubs:=kc.keys()for_,xpub:=rangexpubs{ifxpub.Alias==alias{returntrue}}returnfalse}

通过xpub.Alias我们可以了解到,原来别名跟公钥是绑定的,alias可以看作是公钥的一个属性(当然也属于相应的私钥)。所以前面把公钥放进cache,之后就可以查询别名了。

那么第3步中的createChainKDKey又是如何生成密钥的呢?

blockchain/pseudohsm/pseudohsm.go#L68-L86

func(h*HSM)createChainKDKey(authstring,aliasstring,getbool)(*XPub,bool,error){//1.xprv,xpub,err:=chainkd.NewXKeys(nil)iferr!=nil{returnnil,false,err}//2.id:=uuid.NewRandom()key:=&XKey{ID:id,KeyType:"bytom_kd",XPub:xpub,XPrv:xprv,Alias:alias,}//3.file:=h.keyStore.JoinPath(keyFileName(key.ID.String()))iferr:=h.keyStore.StoreKey(file,key,auth);err!=nil{returnnil,false,errors.Wrap(err,"storingkeys")}//4.return&XPub{XPub:xpub,Alias:alias,File:file},true,nil}

这块代码内容比较清晰,我们可以把它分成4步,分别是:

调用chainkd.NewXKeys生成密钥。其中chainkd对应的是比原代码库中的另一个包"crypto/ed25519/chainkd",从名称上来看,使用的是ed25519算法。如果对前面文章“如何连上一个比原节点”还有印象的话,会记得比原在有新节点连上的时候,就会使用该算法生成一对密钥,用于当次连接进行加密通信。不过需要注意的是,虽然两者都是ed25519算法,但是上次使用的代码却是来自第三方库"github.com/tendermint/go-crypto"的。它跟这次的算法在细节上究竟有哪些不同,目前还不清楚,留待以后合适的机会研究。然后是传入chainkd.NewXKeys(nil)的参数nil,对应的是“随机数生成器”。如果传的是nil,NewXKeys就会在内部使用默认的随机数生成器生成随机数并生成密钥。关于密钥算法相关的内容,在本文中并不探讨。

给当前密钥生成一个唯一的id,在后面用于生成文件名,保存在硬盘上。id使用的是uuid,生成的是一个形如62bc9340-f6a7-4d16-86f0-4be61920a06e这样的全球唯一的随机数

把密钥以文件形式保存在硬盘上。这块内容比较多,下面详细讲。

把公钥相关信息组合在一起,供调用者使用。

我们再详细讲一下第3步,把密钥保存成文件。首先是生成文件名,keyFileName函数对应的代码如下:

blockchain/pseudohsm/key.go#L96-L101

//keyFileNameimplementsthenamingconventionforkeyfiles://UTC--<created_atUTCISO8601>-<addresshex>funckeyFileName(keyAliasstring)string{ts:=time.Now().UTC()returnfmt.Sprintf("UTC--%s--%s",toISO8601(ts),keyAlias)}

注意这里的参数keyAlias实际上应该是keyID,就是前面生成的uuid。写成alias有点误导,已经提交PR#922。最后生成的文件名,形如:UTC--2018-05-07T06-20-46.270917000Z--62bc9340-f6a7-4d16-86f0-4be61920a06e

生成文件名之后,会通过h.keyStore.JoinPath把它放在合适的目录下。通常来说,这个目录是本机数据目录下的keystore,如果你是OSX系统,它应该在你的~/Library/Bytom/keystore,如果是别的,你可以通过下面的代码来确定DefaultDataDir()

关于上面的保存密钥文件的目录,到底是怎么确定的,在代码中其实是有点绕的。不过如果你对这感兴趣的话,我相信你应该能自行找到,这里就不列出来了。如果找不到的话,可以试试以下关键字:pseudohsm.New(config.KeysDir()), os.ExpandEnv(config.DefaultDataDir()), DefaultDataDir(),DefaultBaseConfig()

在第3步的最后,会调用keyStore.StoreKey方法,把它保存成文件。该方法代码如下:

blockchain/pseudohsm/keystore_passphrase.go#L67-L73

func(kskeyStorePassphrase)StoreKey(filenamestring,key*XKey,authstring)error{keyjson,err:=EncryptKey(key,auth,ks.scryptN,ks.scryptP)iferr!=nil{returnerr}returnwriteKeyFile(filename,keyjson)}

EncryptKey里做了很多事情,把传进来的密钥及其它信息利用起来生成了JSON格式的信息,然后通过writeKeyFile把它保存硬盘上。所以在你的keystore目录下,会看到属于你的密钥文件。它们很重要,千万别误删了。

a.wallet.Hsm.XCreate看完了,让我们回到a.pseudohsmCreateKey方法的最后一部分。可以看到,当成功生成key之后,会返回一个NewSuccessResponse(xpub),把与公钥相关的信息返回给前端。它会被jsonHandler自动转换成JSON格式,通过http返回过去。

感谢各位的阅读,以上就是“比原怎么通过create-key接口创建密钥”的内容了,经过本文的学习后,相信大家对比原怎么通过create-key接口创建密钥这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是,小编将为大家推送更多相关知识点的文章,欢迎关注!

域名注册
购买VPS主机

您或许对下面这些文章有兴趣:                    本月吐槽辛苦排行榜

看贴要回贴有N种理由!看帖不回贴的后果你懂得的!


评论内容 (*必填):
(Ctrl + Enter提交)   

部落快速搜索栏

各类专题梳理

网站导航栏

X
返回顶部