中心化的数字藏品交易平台需求为每一个用户生成私钥,这样才能在铸造和交易成功时,将数字藏品存入对应的账户地址中。
生成一个私钥的办法
pbkdf2.Key() 生成秘钥函数
PBKDF2(Password-Based Key Derivation Function) 是一个用来导出密钥的函数,常用于生成加密的暗码。
它的基本原理是经过一个伪随机函数(例如HMAC函数、sha512等),把明文(password)和一个盐值(salt)作为一个输入参数,然后重复进行运算,并最终发生秘钥。
如果重复的次数足够大,破解的本钱就会变得很高。而盐值的添加也会增加“彩虹表”攻击的难度。
PBKDF2函数的语法界说
DK = PBKDF2(PRF, Password, Salt, c, dkLen ,Hash algorithm)
- PRF是一个伪随机函数,例如HASH_HMAC函数,它会输出长度为hLen的结果。
- Password是用来生成密钥的原文暗码。
- Salt是一个加密用的盐值。
- c是进行重复核算的次数。
- dkLen是希望得到的密钥的长度。
- DK是最终发生的密钥。
以下为运用助记词生成私钥的代码
package pbkdf2
import (
"crypto/rand"
"crypto/sha512"
"golang.org/x/crypto/pbkdf2"
)
const (
Mnemonic = "blood twenty adjust search crime conversation tag directory joke leaf express interest"
password = ""
)
func encryptPwdWithSalt(password string) (*ecdsa.PrivateKey, *ecdsa.PublicKey) {
seed := pbkdf2.Key([]byte(Mnemonic), []byte("mnemonic"+password), 2048, 64, sha512.New)
}
// []byte(Mnemonic):助记词
// []byte("mnemonic"+password) :salt盐值
// 2048:重复核算的次数
// 64:回来的秘钥长度
// sha512.New:哈希算法
HMAC 生成摘要算法
HMAC算法中文名称叫哈希音讯认证码,英文全称是Hash-based Message Authentication Code。它的算法是依据某个哈希散列函数(主要是SHA系列和MD系列),以一个密钥和一个音讯为输入,生成一个音讯摘要作为输出。HMAC算法与其他哈希散列算法最大差异就是需求有密钥。它的算法函数是利用分组暗码来建立的一个单向Hash函数。
HMAC的密钥可以是任何长度,如果密钥的长度超过了摘要算法信息分组的长度,则首要运用摘要算法核算密钥的摘要作为新的密钥。一般不建议运用太短的密钥,由于密钥的长度与安全强度是相关的。通常选取密钥长度不小于所选用摘要算法输出的信息摘要的长度。
HMAC算法golang封装的代码详细解析
//创立运算目标,HMAC需求两个参数:hash函数和key
hmac := hmac.New(sha512.New, []byte(BitcoinSeed))
//将明文写入到hmac中
_, err := hmac.Write([]byte(seed))
if err != nil {
return nil, nil
}
//hmac目标对写入数据的运算,生成的参数为字节
intermediary := hmac.Sum(nil)
PrivKeyFromBytes 创立私钥、公钥对
// PrivKeyFromBytes 依据私钥随机数D回来公私钥
func PrivKeyFromBytes(curve elliptic.Curve, pk []byte) (*PrivateKey, *PublicKey) {
// 依据字节pk,回来x,y
x, y := curve.ScalarBaseMult(pk)
// 界说一个私钥结构体,结构体中包含:公钥结构体
priv := &PrivateKey{
PublicKey: e.PublicKey{
Curve: curve,
X: x,
Y: y,
},
D: new(big.Int).SetBytes(pk),
}
return priv, (*PublicKey)(&priv.PublicKey)
}
用这个函数来创立私钥
keyBytes := intermediary[:32] // 私钥
return ecdsa.PrivKeyFromBytes(ecdsa.S256(), keyBytes)
全部代码
func NewKey(mnemonic, password string) (*ecdsa.PrivateKey, *ecdsa.PublicKey) {
seed := pbkdf2.Key([]byte(mnemonic), []byte("mnemonic"+password), 2048, 64, sha512.New)
hmac := hmac.New(sha512.New, []byte(BitcoinSeed))
_, err := hmac.Write([]byte(seed))
if err != nil {
return nil, nil
}
intermediary := hmac.Sum(nil)
keyBytes := intermediary[:32] // 私钥
return ecdsa.PrivKeyFromBytes(ecdsa.S256(), keyBytes)
}
生成多个私钥的办法
上诉参数中有 password 作为参数。这里把数据库里的id作为参数传入。每次都是用相同的办法,则生成的私钥是必定的。有多少用户,就能生成多少个私钥。
此时只保存原始的 mnemonic 即可。