golang笔记-区块链密码学01
PBKDF2(Password-Based Key Derivation Function)
是一个用来导出密钥的函数,常用于生成加密的密码。
它的基本原理是通过一个伪随机函数(例如HMAC函数、sha512等),把明文(password)和一个盐值(salt)作为一个输入参数,然后重复进行运算,并最终产生秘钥。
如果重复的次数足够大,破解的成本就会变得很高。而盐值的添加也会增加“彩虹表”攻击的难度。
用户密码采用PBKDF2算法存储,比较安全。
PBKDF2函数的语法定义
DK = PBKDF2(PRF, Password, Salt, c, dkLen ,Hash algorithm)
以下为使用助记词生成私钥的代码
package pbkdf2
import (
"crypto/rand"
"crypto/sha512"
"golang.org/x/crypto/pbkdf2"
)
const (
Mnemonic = "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算法中文名称叫哈希消息认证码,英文全称是Hash-based Message Authentication Code。它的算法是基于某个哈希散列函数(主要是SHA系列和MD系列),以一个密钥和一个消息为输入,生成一个消息摘要作为输出。HMAC算法与其他哈希散列算法最大区别就是需要有密钥。它的算法函数是利用分组密码来建立的一个单向Hash函数。 下表显示具体的算法对应输出摘要的长度。
算法 | 摘要长度(位) | 备注 |
---|---|---|
HmacMD5 | 128 | BouncyCastle实现 |
HmacSHA1 | 160 | (20个字节) BouncyCastle实现 |
HmacSHA256 | 256 | BouncyCastle实现 |
HmacSHA384 | 384 | BouncyCastle实现 |
HmacSHA512 | 512 | JAVA6实现 |
HmacMD2 | 128 | BouncyCastle实现 |
HmacMD4 | 128 | BouncyCastle实现 |
HmacSHA224 | 224 | BouncyCastle实现 |
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)
用golang使用HMAC算法的距举例
package main
import (
"crypto/hmac"
"crypto/md5"
"crypto/sha1"
"encoding/hex"
"fmt"
)
func Md5(data string) string {
md5 := md5.New()
md5.Write([]byte(data))
md5Data := md5.Sum([]byte(""))
return hex.EncodeToString(md5Data)
}
func Hmac(key, data string) string {
hmac := hmac.New(md5.New, []byte(key))
hmac.Write([]byte(data))
return hex.EncodeToString(hmac.Sum(nil)
}
func Sha1(data string) string {
sha1 := sha1.New()
sha1.Write([]byte(data))
return hex.EncodeToString(sha1.Sum(nil))
}
func main() {
fmt.Println(Md5("hello"))
fmt.Println(Hmac("key2", "hello"))
fmt.Println(Sha1("hello"))
}
根据作为参数作为字节切片传递的私钥返回“曲线”的私钥和公钥。
我们应该知道,可以从私钥生成公钥。所以拥有私钥相当于拥有整个密钥对。
以下为生成密钥对的代码:
func PrivKeyFromBytes(curve elliptic.Curve, pk []byte) (*PrivateKey, *PublicKey) {
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)
}
*ecdsa.PrivateKey 是 PublicKey 和 PrivateKey 的结构。这也是从原始字节 PrivateKey 检索密钥对的函数。
参考文档
以上,就是今天分享的全部内容了,希望大家通过以上笔记可以解决自己的实际需求,解决自己目前所遇到的问题。
如果文章中如果有不太正确的地方,欢迎指正,可以添加我的个人微信,备注:地区-职业方向-昵称,欢迎来撩,加入golang技术交流群,与更多的golang开发者、技术大佬学习交流。
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!