美文网首页
Go语言使用椭圆曲线进行数字签名

Go语言使用椭圆曲线进行数字签名

作者: realguan | 来源:发表于2019-11-24 11:45 被阅读0次
    package main
    
    import (
        "crypto/ecdsa"
        "crypto/elliptic"
        "crypto/rand"
        "crypto/sha1"
        "crypto/x509"
        "encoding/pem"
        "fmt"
        "math/big"
        "os"
    )
    
    func main() {
        GenerateEccKey()
        src := []byte("椭圆曲线进行数字签名")
        rText,sText := EccSignature(src,"eccPrivate.pem")
        bl := EccVerify(src,rText,sText,"eccPublic.pem")
        fmt.Println(bl)
    }
    
    // 生成密钥对
    func GenerateEccKey() {
        // --------私钥写入磁盘--------
        // 1 使用ecdsa生成密钥对
        privateKey,err := ecdsa.GenerateKey(elliptic.P521(),rand.Reader)
        if err != nil {
            panic(err)
        }
        // 2 使用x509将私钥进行序列化
        derText,err := x509.MarshalECPrivateKey(privateKey)
        if err != nil {
            panic(err)
        }
        // 3 将序列化后的字符串放入pem.Block结构体中
        block := pem.Block{
            Type:"ecdsa private key",
            Bytes:derText,
        }
        // 4 使用pem编码
        file,err := os.Create("eccPrivate.pem")
        if err != nil {
            panic(err)
        }
        pem.Encode(file,&block)
        file.Close()
    
        // --------公钥写入磁盘--------
        // 1 从私钥中获取公钥
        publicKey := privateKey.PublicKey
        // 2 x509序列化公钥
        derText,err = x509.MarshalPKIXPublicKey(&publicKey)
        if err != nil {
            panic(err)
        }
        // 3 将序列化后的字符串放入pem.Block 中
        block = pem.Block{
            Type:"ecdsa public key",
            Bytes:derText,
        }
        // 4 使用pem编码
        file,err = os.Create("eccPublic.pem")
        if err != nil {
            panic(err)
        }
        pem.Encode(file,&block)
        file.Close()
    }
    
    // ecdsa 签名
    func EccSignature(plainText []byte,privName string) (rText,sText []byte) {
        // 1 打开私钥将内容读取出来
        file,err := os.Open(privName)
        if err != nil {
            panic(err)
        }
        fileInfo,err := file.Stat()
        if err != nil {
            panic(err)
        }
        buf := make([]byte,fileInfo.Size())
        file.Read(buf)
        file.Close()
        // 2 pem解码
        block,_ := pem.Decode(buf)
        // 3 x509解析
        privateKey,err := x509.ParseECPrivateKey(block.Bytes)
        if err != nil {
            panic(err)
        }
        // 4 对原始数据进行hash运算得到散列值
        hashText := sha1.Sum(plainText)
        // 5 进行数据签名
        r,s,err := ecdsa.Sign(rand.Reader,privateKey,hashText[:])
        if err != nil {
            panic(err)
        }
        // 6 对r,s内存中的数据进行格式化
        rText,err = r.MarshalText()
        if err != nil {
            panic(err)
        }
        sText,err = s.MarshalText()
        if err != nil {
            panic(err)
        }
        return
    }
    
    // ecdsa签名认证
    func EccVerify(plainText,rText,sText []byte,pubFile string) bool {
        // 1 打开公钥文件,将内容读取出来
        file,err := os.Open(pubFile)
        if err != nil {
            panic(err)
        }
        fileInfo,err := file.Stat()
        if err != nil {
            panic(err)
        }
        buf := make([]byte,fileInfo.Size())
        file.Read(buf)
        file.Close()
        // 2 pem解码
        block,_ := pem.Decode(buf)
        // 3 x509解析
        pubInterface,err := x509.ParsePKIXPublicKey(block.Bytes)
        if err != nil {
            panic(err)
        }
        // 4 类型断言获取公钥
        publicKey := pubInterface.(*ecdsa.PublicKey)
        // 5 对原始数据进行hash运算得到散列值
        hashText := sha1.Sum(plainText)
        // 6 签名认证
        // 将rText,sText 转换成 int
        var r,s big.Int
        r.UnmarshalText(rText)
        s.UnmarshalText(sText)
        bl := ecdsa.Verify(publicKey,hashText[:],&r,&s)
        return bl
    }
    

    相关文章

      网友评论

          本文标题:Go语言使用椭圆曲线进行数字签名

          本文链接:https://www.haomeiwen.com/subject/mgkhwctx.html