ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

密码技术--椭圆曲线算法EDCSA数字签名及Go语言应用

2021-05-26 00:02:26  阅读:231  来源: 互联网

标签:x509 err nil pem 数字签名 -- file Go panic


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
}

标签:x509,err,nil,pem,数字签名,--,file,Go,panic
来源: https://blog.csdn.net/weixin_38299404/article/details/117267252

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有