golangsha1解码_golang 椭圆曲线加密使用ecdsa

本文介绍了如何在Golang中使用ECDSA进行非对称加密,包括生成公钥和私钥,对文本进行签名,以及验证签名。ECDSA是一种基于椭圆曲线的加密算法,安全性比RSA更高。示例代码展示了如何实现签名和校验过程。
摘要由CSDN通过智能技术生成

非对称加密算法有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 := "20180619zafes20180619zafes20180619zafessss"//至少36位

//随机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)

}

借鉴使用……

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值