前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Golang封装ecdsa(ecc)相关工具类:密钥生成、序列化、签名、验签

Golang封装ecdsa(ecc)相关工具类:密钥生成、序列化、签名、验签

作者头像
Happyjava
发布2020-03-27 00:05:26
2.6K0
发布2020-03-27 00:05:26
举报
文章被收录于专栏:Happy的分享Happy的分享

通过Go语言封装一个椭圆曲线算法(ecdsa),方便自己使用。签名算法直接写死sha256了,有需要自行修改即可。

ecc_utils.go

代码语言:javascript
复制
package ecc

import (
	"crypto/ecdsa"
	"crypto/elliptic"
	"crypto/rand"
	"crypto/sha256"
	"crypto/x509"
	"encoding/base64"
	"encoding/hex"
	"math/big"
	"strings"
)

func GenKeyPair() (privateKey string, publicKey string, e error) {
	priKey, e := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
	if e != nil {
		return "", "", e
	}
	ecPrivateKey, e := x509.MarshalECPrivateKey(priKey)
	if e != nil {
		return "", "", e
	}
	privateKey = base64.StdEncoding.EncodeToString(ecPrivateKey)

	X := priKey.X
	Y := priKey.Y
	xStr, e := X.MarshalText()
	if e != nil {
		return "", "", e
	}
	yStr, e := Y.MarshalText()
	if e != nil {
		return "", "", e
	}
	public := string(xStr) + "+" + string(yStr)
	publicKey = base64.StdEncoding.EncodeToString([]byte(public))
	return
}

func BuildPrivateKey(privateKeyStr string) (priKey *ecdsa.PrivateKey, e error) {
	bytes, e := base64.StdEncoding.DecodeString(privateKeyStr)
	if e != nil {
		return nil, e
	}
	priKey, e = x509.ParseECPrivateKey(bytes)
	if e != nil {
		return nil, e
	}
	return
}

func BuildPublicKey(publicKeyStr string) (pubKey *ecdsa.PublicKey, e error) {
	bytes, e := base64.StdEncoding.DecodeString(publicKeyStr)
	if e != nil {
		return nil, e
	}
	split := strings.Split(string(bytes), "+")
	xStr := split[0]
	yStr := split[1]
	x := new(big.Int)
	y := new(big.Int)
	e = x.UnmarshalText([]byte(xStr))
	if e != nil {
		return nil, e
	}
	e = y.UnmarshalText([]byte(yStr))
	if e != nil {
		return nil, e
	}
	pub := ecdsa.PublicKey{Curve: elliptic.P256(), X: x, Y: y}
	pubKey = &pub
	return
}

func Sign(content string, privateKeyStr string) (signature string, e error) {
	priKey, e := BuildPrivateKey(privateKeyStr)
	if e != nil {
		return "", e
	}
	r, s, e := ecdsa.Sign(rand.Reader, priKey, []byte(hash(content)))
	if e != nil {
		return "", e
	}
	rt, e := r.MarshalText()
	st, e := s.MarshalText()
	signStr := string(rt) + "+" + string(st)
	signature = hex.EncodeToString([]byte(signStr))
	return
}

func VerifySign(content string, signature string, publicKeyStr string) bool {
	decodeSign, e := hex.DecodeString(signature)
	if e != nil {
		return false
	}
	split := strings.Split(string(decodeSign), "+")
	rStr := split[0]
	sStr := split[1]
	rr := new(big.Int)
	ss := new(big.Int)
	e = rr.UnmarshalText([]byte(rStr))
	e = ss.UnmarshalText([]byte(sStr))
	pubKey, e := BuildPublicKey(publicKeyStr)
	if e != nil {
		return false
	}
	return ecdsa.Verify(pubKey, []byte(hash(content)), rr, ss)
}

// Hash算法,这里是sha256,可以根据需要自定义
func hash(data string) string {
	sum := sha256.Sum256([]byte(data))
	return base64.StdEncoding.EncodeToString(sum[:])
}
复制代码

ecc_utils_test.go

代码语言:javascript
复制
package ecc

import "testing"

const pubKey = "MTEzODUyMzM5MzU4ODk1MzEzNzg3MzY2NzYwODUwMjE2MjQzNTE0OTc0NjkzMzM2NzA4OTYzNDY0MDk1MTUxMDkyMjY5MjM0NjE3NjMyKzc5NzY5NDM5NTI4NjcxMzc4OTQ3ODYyMzY0MjQ1ODg4ODA0MTEyMDgwOTM4MjgyNjI0MTY4NDUwNjE0NTg4MDc3MDk0MTUxNzk4NzM3"
const priKey = "MHcCAQEEIBC7/AKbbIHyVF4XJQmvqwrJMX8c8dU2JP6NcReYDlJ1oAoGCCqGSM49AwEHoUQDQgAE+7Yj9jOgDCRccssUMp1NVJExBrJCv6H8LsYUqS8lfSCwW+cdXcnmNDHM5Z2K05bJywyDIWU3f+53z0HK0I4/0Q=="
const content = "Happyjava not only java"
const signature = "36393733373630313538383036323831323937313232353733313837333336373132363935303734303237373233373433363139373530313438383239303532303635383433333733313336362b35363137383339343939383534303631323730373630343438313135333633383339333535303836313830343737333331383935333532383537333730363035313839383939353330363939"

func TestGenKeyPair(t *testing.T) {
	privateKey, publicKey, e := GenKeyPair()
	if e != nil {
		t.Error(e)
		return
	}
	t.Log("pubKey:", publicKey)
	t.Log("priKey:", privateKey)
}

func TestBuildPublicKey(t *testing.T) {
	publicKey, e := BuildPublicKey(pubKey)
	if e != nil {
		t.Error(e)
		return
	}
	t.Log("publicKey:", publicKey)
}

func TestBuildPrivateKey(t *testing.T) {
	privateKey, e := BuildPrivateKey(priKey)
	if e != nil {
		t.Error(e)
		return
	}
	t.Log("privateKey:", privateKey)
}

func TestSign(t *testing.T) {
	signature, e := Sign(content, priKey)
	if e != nil {
		t.Error(e)
	} else {
		t.Log("signature:", signature)
	}
}

func TestVerifySign(t *testing.T) {
	verify := VerifySign(content, signature, pubKey)
	t.Log("verify:", verify)
}

复制代码
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2020年03月25日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档