关于密码学:密码技术椭圆曲线EDCSA数字签名及Go语言应用

41次阅读

共计 2779 个字符,预计需要花费 7 分钟才能阅读完成。

1. 生成秘钥对并写入磁盘文件

1. 应用 ecdsa 生成秘钥对

2. 将私钥写入磁盘

  • 应用 x509 进行反序列化
  • 将失去的切片字符串放到 pem.Block 构造体中
  • 应用 pem 编码

3. 将公钥写入磁盘

  • 从私钥中失去公钥
  • 应用 x509 进行序列化
  • 将失去的切片字符串放入 pem.Block 构造体中
  • 应用 pem 编码

2. 应用私钥进行数字签名

1. 关上私钥文件,将内容读出来

2. 应用 pem 进行数据解码

3. 应用 x509 对数据还原

4. 对原始数据进行哈希运算

5. 进行数字签名
func Sign(rand io.Reader, priv PrivateKey, hash []byte) (r, s big.Int, err error)
6. 返回值为指针,因而须要将该地址指向内存中的数据进行序列话

3. 应用公钥验证数字签名

1. 关上公钥文件,读出数据

2. 应用 pem 进行解码

3. 应用 x509 进行公钥数据还原
func ParsePKIXPublicKey(derBytes []byte) (pub interface{}, err error)

4. 因为上一步返回的是一个接口类型,因而须要进行类型断言,将接口类型转换为公钥

5. 对原始数据进行哈希运算

6. 验签

4.go 中利用

package main

import (
    "crypto/ecdsa"
    "crypto/elliptic"
    "crypto/rand"
    "crypto/x509"
    "encoding/pem"
    "os"
    "crypto/sha256"
    "math/big"
)

func GenerateEcdsaKey () {
    //1. 应用 ecdsa 生成秘钥对
    privateKey, err := ecdsa.GenerateKey(elliptic.P521(), rand.Reader)
    if err != nil {panic(err)
    }
    //2. 将私钥写入磁盘
    //* 应用 x509 进行反序列化
    ecPrivateKey, err := x509.MarshalECPrivateKey(privateKey)
    if err != nil {panic(err)
    }
    //* 将失去的切片字符串放到 pem.Block 构造体中
    block := pem.Block{
        Type:    "ecdsa private key",
        Headers: nil,
        Bytes:   ecPrivateKey,
    }
    //* 应用 pem 编码
    file, err := os.Create("ecPrivate.pem")
    if err != nil {panic(err)
    }
    defer file.Close()
    err = pem.Encode(file, &block)
    if err != nil {panic(err)
    }
    //3. 将公钥写入磁盘
    //* 从私钥中失去公钥
    publicKey := privateKey.PublicKey
    //* 应用 x509 进行序列化
    ecPublicKey, err := x509.MarshalPKIXPublicKey(&publicKey)
    if err != nil {panic(err)
    }
    //* 将失去的切片字符串放入 pem.Block 构造体中
    block = pem.Block{
        Type:    "ecdsa public key",
        Headers: nil,
        Bytes:   ecPublicKey,
    }
    //* 应用 pem 编码
    file, err = os.Create("ecPublic.pem")
    if err != nil {panic(err)
    }
    defer file.Close()
    pem.Encode(file, &block)
}

// 签名
func SignECDSA (plainText []byte, priFileName string) (rText, sText []byte) {
    //1. 关上私钥文件,将内容读出来
    file, err := os.Open(priFileName)
    if err != nil {panic(err)
    }
    defer file.Close()
    fileInfo, err := file.Stat()
    if err != nil {panic(err)
    }
    buf := make([]byte, fileInfo.Size())
    _, err = file.Read(buf)
    if err != nil {panic(err)
    }
    //2. 应用 pem 进行数据解码
    block, _ := pem.Decode(buf)
    //3. 应用 x509 对数据还原
    privateKey, err := x509.ParseECPrivateKey(block.Bytes)
    if err != nil {panic(err)
    }
    //4. 对原始数据进行哈希运算
    hashText := sha256.Sum256(plainText)
    //5. 进行数字签名
    var r, s *big.Int // 留神这里
    r, s, err = ecdsa.Sign(rand.Reader, privateKey, hashText[:])
    if err != nil {panic(err)
    }
    //6. 返回值为指针,因而须要将该地址指向内存中的数据进行序列话
    rText, err = r.MarshalText()
    if err != nil {panic(err)
    }
    sText, err = s.MarshalText()
    if err != nil {panic(err)
    }
    return rText,sText
}

// 验签
func VerifyECDSA (plainText, rText, sText []byte, pubFileName string) bool {
    //1. 关上公钥文件,读出数据
    file, err := os.Open(pubFileName)
    if err != nil {panic(err)
    }
    defer file.Close()
    fileInfo, err := file.Stat()
    if err != nil {panic(err)
    }
    buf := make([]byte, fileInfo.Size())
    _, err = file.Read(buf)
    if err != nil {panic(err)
    }
    //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. 对原始数据进行哈希运算
    hashText := sha256.Sum256(plainText)
    //6. 验签
    var r, s big.Int
    r.UnmarshalText(rText)
    s.UnmarshalText(sText)
    res := ecdsa.Verify(publicKey, hashText[:], &r, &s)
    return res
}

正文完
 0