golang 椭圆曲线加密使用ecdsa
Posted 区块链兄弟
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了golang 椭圆曲线加密使用ecdsa相关的知识,希望对你有一定的参考价值。
▲点击蓝字,轻松关注
来源:简书
原文链接:http://t.cn/RFnWcox
本文约4000字+,阅读(观看)需要23分钟
非对称加密算法有RSA、ECDSA,对极大整数做因数分解的难度决定了RSA算法的可靠性,ECDSA为椭圆曲线加密算法,是基于椭圆方程公式,所以安全性要高于RSA。
这里说下使用ecdsa做签名和校验,并不讲原理;
golang封装的ecdsa目前只有用私钥加密,公钥做校验,没有解密环节;所以目前可以应用于数字签名;
以下为封装:
/** 通过一个随机key创建公钥和私钥 随机key至少为36位 */func getEcdsaKey(randKey string) (*ecdsa.PrivateKey, ecdsa.PublicKey, error){
var err error
var prk *ecdsa.PrivateKey
var puk ecdsa.PublicKey
var curve elliptic.Curve
lenth := len(randKey) if lenth < 224/8 {
err =errors.New("私钥长度太短,至少为36位!") return prk,puk,err
} if lenth > 521/8 + 8 {
curve = elliptic.P521()
}else if lenth > 384/8 + 8 {
curve = elliptic.P384()
}else if lenth > 256/8 + 8 {
curve = elliptic.P256()
}else if lenth > 224/8 + 8 {
curve = elliptic.P224()
}
prk, err = ecdsa.GenerateKey(curve,strings.NewReader(randKey)) if err != nil { return prk, puk, err
}
puk = prk.PublicKey return prk, puk, err
}/** 对text加密,text必须是一个hash值,例如md5、sha1等 使用私钥prk 使用随机熵增强加密安全,安全依赖于此熵,randsign 返回加密结果,结果为数字证书r、s的序列化后拼接,然后用hex转换为string */func sign(text []byte,randSign string,prk *ecdsa.PrivateKey) (string, error) {
r, s, err := ecdsa.Sign(strings.NewReader(randSign), prk, text) if err != nil { return "", err
}
rt, err := r.MarshalText() if err != nil { return "", err
}
st, err := s.MarshalText() if err != nil { return "", err
}
var b bytes.Buffer
w := gzip.NewWriter(&b)
defer w.Close()
_, err = w.Write([]byte(string(rt) + "+" + string(st))) if err != nil { return "", err
}
w.Flush() return hex.EncodeToString(b.Bytes()), nil}/** 证书分解 通过hex解码,分割成数字证书r,s */func getSign( signature string) (rint, sint big.Int, err error) {
byterun, err := hex.DecodeString(signature) if err != nil {
err = errors.New("decrypt error, "+ err.Error()) return
}
r, err := gzip.NewReader(bytes.NewBuffer(byterun)) if err != nil {
err = errors.New("decode error,"+err.Error()) return
}
defer r.Close()
buf := make([]byte, 1024)
count, err := r.Read(buf) if err != nil {
fmt.Println("decode = ",err)
err = errors.New("decode read error," + err.Error()) return
}
rs := strings.Split(string(buf[:count]),"+") if len(rs) != 2 {
err = errors.New("decode fail") return
}
err = rint.UnmarshalText([]byte(rs[0])) if err != nil {
err = errors.New("decrypt rint fail, "+ err.Error()) return
}
err = sint.UnmarshalText([]byte(rs[1])) if err != nil {
err = errors.New("decrypt sint fail, "+ err.Error()) return
} return}/** 校验文本内容是否与签名一致 使用公钥校验签名和文本内容 */func verify(text []byte, signature string, key ecdsa.PublicKey) (bool, error) {
rint, sint, err :=getSign(signature) if err != nil { return false, err
}
result := ecdsa.Verify(&key,text,&rint,&sint) return result, nil}/** hash加密 使用md5加密 */func hashtext(text, salt string) ([]byte) {
Md5Inst := md5.New()
Md5Inst.Write([]byte(text))
result := Md5Inst.Sum([]byte(salt)) return result
}
func main() { //随机熵,用于加密安全
randSign := "20180619zafes"
//随机key,用于创建公钥和私钥
randKey := "fb0f7279c18d4394594fc9714797c9680335a320"
//创建公钥和私钥
prk, puk, err := getEcdsaKey(randKey) if err != nil {
fmt.Println(err)
} //hash加密使用md5用到的salt
salt := "131ilzaw"
//待加密的明文
text := "hlloaefaefaefaefaefaefaefhelloaefaefaefaefaefaefaefhelloaefaefaefaefaefaefaef"
//text1 := "hlloaefaefaefaefaefaefaefhelloaefaefaefaefaefaefaefhelloaefaefaefaefaefaefaef1"
//hash取值
htext := hashtext(text,salt) //htext1 := hashtext(text1,salt)
//hash值编码输出
fmt.Println(hex.EncodeToString(htext)) //hash值进行签名
result, err := sign(htext,randSign,prk) if err != nil {
fmt.Println(err)
} //签名输出
fmt.Println(result) //签名与hash值进行校验
tmp, err := verify(htext,result,puk)
fmt.Println(tmp)
}
借鉴使用……
文章发布只为分享区块链技术内容,版权归原作者所有,观点仅代表作者本人,绝不代表区块链兄弟赞同其观点或证实其描述。
猜猜你喜欢
分享 | 2018年度中国区块链专利报告 |
|
Fomo3D死亡3分钟:黑客用0.8ETH赢下了10000个ETH |
|
点击“阅读原文”参与区块链问题讨论
以上是关于golang 椭圆曲线加密使用ecdsa的主要内容,如果未能解决你的问题,请参考以下文章