Skip to content

Commit

Permalink
Merge branch 'main' of https://github.com/lei006/go-assist into main
Browse files Browse the repository at this point in the history
  • Loading branch information
lei006 committed Mar 6, 2021
2 parents f460b05 + 15e802c commit d370d5b
Show file tree
Hide file tree
Showing 3 changed files with 373 additions and 0 deletions.
175 changes: 175 additions & 0 deletions crypto/ecc_tool/ecc_sign.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,175 @@
package ecc_tool

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

type EccSign struct {
Rtext string `json:"rtext"`
Stext string `json:"stext"`
}

func (this *EccSign) ToJson() (string, error) {
b, err := json.Marshal(this)
if err != nil {
return "", err
}
return string(b), nil
}

func (this *EccSign) FromJson(data_str string) error {
data := []byte(data_str)
err := json.Unmarshal(data, this)
return err
}

//生成ECC椭圆曲线密钥对
func GenerateECCKeyString() (string, string, error) {

//生成密钥对
privateKey, err := ecdsa.GenerateKey(elliptic.P521(), rand.Reader)
if err != nil {
return "", "", err
}

//x509编码
eccPrivateKey, err := x509.MarshalECPrivateKey(privateKey)
if err != nil {
return "", "", err
}
//pem编码
privateBlock := pem.Block{
Type: "ecc private key",
Bytes: eccPrivateKey,
}
tmp := pem.EncodeToMemory(&privateBlock)
if tmp == nil {
return "", "", errors.New("error")
}

private_str := string(tmp)

//保存公钥
publicKey := privateKey.PublicKey

//x509编码
eccPublicKey, err := x509.MarshalPKIXPublicKey(&publicKey)
if err != nil {
return "", "", err
}
//pem编码
block := pem.Block{Type: "ecc public key", Bytes: eccPublicKey}
tmp = pem.EncodeToMemory(&block)
if tmp == nil {
return "", "", errors.New("error")
}
//公钥字符串
publish_str := string(tmp)

return publish_str, private_str, nil
}

//取得ECC私钥
func PrivateKeyFromString(private_str string) (*ecdsa.PrivateKey, error) {
//读取私钥

//pem解码
block, _ := pem.Decode(([]byte)(private_str))
//x509解码
privateKey, err := x509.ParseECPrivateKey(block.Bytes)
if err != nil {
return nil, err
}

return privateKey, nil
}

//取得ECC公钥
func PublicKeyFromString(publish_str string) (*ecdsa.PublicKey, error) {
//读取公钥
//pem解密
block, _ := pem.Decode(([]byte)(publish_str))

//x509解密
publicInterface, err := x509.ParsePKIXPublicKey(block.Bytes)
if err != nil {
return nil, err
}
publicKey := publicInterface.(*ecdsa.PublicKey)
return publicKey, nil
}

//对消息的散列值生成数字签名
func Sign(msg string, private_str string) (string, error) {
//取得私钥
privateKey, err := PrivateKeyFromString(private_str)
if err != nil {
return "", err
}

//计算哈希值
hash := sha256.New()
//填入数据
hash.Write([]byte(msg))
bytes := hash.Sum(nil)
//对哈希值生成数字签名
r, s, err := ecdsa.Sign(rand.Reader, privateKey, bytes)
if err != nil {
return "", err
}
rtext, err := r.MarshalText()
if err != nil {
return "", err
}
stext, err := s.MarshalText()
if err != nil {
return "", err
}

sign := &EccSign{
Rtext: string(rtext),
Stext: string(stext),
}

tmp_str, err := sign.ToJson()
if err != nil {
return "", err
}

return tmp_str, nil
}

//验证数字签名
func VerifySign(msg string, sign string, publish_key_str string) bool {
//读取公钥
publicKey, err := PublicKeyFromString(publish_key_str)
if err != nil {
return false
}

ecc_sign := EccSign{}
err = ecc_sign.FromJson(sign)
if err != nil {
return false
}
//计算哈希值
hash := sha256.New()
hash.Write([]byte(msg))
bytes := hash.Sum(nil)

//验证数字签名
var r, s big.Int
r.UnmarshalText([]byte(ecc_sign.Rtext))
s.UnmarshalText([]byte(ecc_sign.Stext))

verify := ecdsa.Verify(publicKey, bytes, &r, &s)
return verify
}
130 changes: 130 additions & 0 deletions crypto/ecc_tool/ecc_sign_file.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
package ecc_tool

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

//生成ECC椭圆曲线密钥对,保存到文件
func GenerateECCKey() {
//生成密钥对
privateKey, err := ecdsa.GenerateKey(elliptic.P521(), rand.Reader)
if err != nil {
panic(err)
}

//保存私钥
//生成文件
privatefile, err := os.Create("eccprivate.pem")
if err != nil {
panic(err)
}
//x509编码
eccPrivateKey, err := x509.MarshalECPrivateKey(privateKey)
if err != nil {
panic(err)
}
//pem编码
privateBlock := pem.Block{
Type: "ecc private key",
Bytes: eccPrivateKey,
}
pem.Encode(privatefile, &privateBlock)

//保存公钥
publicKey := privateKey.PublicKey
//创建文件
publicfile, err := os.Create("eccpublic.pem")
//x509编码
eccPublicKey, err := x509.MarshalPKIXPublicKey(&publicKey)
if err != nil {
panic(err)
}
//pem编码
block := pem.Block{Type: "ecc public key", Bytes: eccPublicKey}
pem.Encode(publicfile, &block)
}

//取得ECC私钥
func GetECCPrivateKey(path string) *ecdsa.PrivateKey {
//读取私钥
file, err := os.Open(path)
if err != nil {
panic(err)
}
defer file.Close()
info, _ := file.Stat()
buf := make([]byte, info.Size())
file.Read(buf)
//pem解码
block, _ := pem.Decode(buf)
//x509解码
privateKey, err := x509.ParseECPrivateKey(block.Bytes)
if err != nil {
panic(err)
}
return privateKey
}

//取得ECC公钥
func GetECCPublicKey(path string) *ecdsa.PublicKey {
//读取公钥
file, err := os.Open(path)
if err != nil {
panic(err)
}
defer file.Close()
info, _ := file.Stat()
buf := make([]byte, info.Size())
file.Read(buf)
//pem解密
block, _ := pem.Decode(buf)
//x509解密
publicInterface, err := x509.ParsePKIXPublicKey(block.Bytes)
if err != nil {
panic(err)
}
publicKey := publicInterface.(*ecdsa.PublicKey)
return publicKey
}

//对消息的散列值生成数字签名
func SignECC(msg []byte, path string) ([]byte, []byte) {
//取得私钥
privateKey := GetECCPrivateKey(path)
//计算哈希值
hash := sha256.New()
//填入数据
hash.Write(msg)
bytes := hash.Sum(nil)
//对哈希值生成数字签名
r, s, err := ecdsa.Sign(rand.Reader, privateKey, bytes)
if err != nil {
panic(err)
}
rtext, _ := r.MarshalText()
stext, _ := s.MarshalText()
return rtext, stext
}

//验证数字签名
func VerifySignECC(msg []byte, rtext, stext []byte, path string) bool {
//读取公钥
publicKey := GetECCPublicKey(path)
//计算哈希值
hash := sha256.New()
hash.Write(msg)
bytes := hash.Sum(nil)
//验证数字签名
var r, s big.Int
r.UnmarshalText(rtext)
s.UnmarshalText(stext)
verify := ecdsa.Verify(publicKey, bytes, &r, &s)
return verify
}
68 changes: 68 additions & 0 deletions examples/ecc_sign/ecc_sing_demo.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
package main

import (
"fmt"

"github.com/lei006/go-assist/crypto/ecc_tool"
)

func test_sign(index int) {

//生成ECC密钥对文件
pub_key, pri_key, err := ecc_tool.GenerateECCKeyString()
if err != nil {
fmt.Println("生成密钥对出错")
return
}

fmt.Println(pub_key)
fmt.Println(pri_key)

//模拟发送者
//要发送的消息
msg := "hello world"
//生成数字签名
sign, err := ecc_tool.Sign(msg, pri_key)
if err != nil {
fmt.Println("对数据签名出错")
return
}
//模拟接受者
//接受到的消息
acceptmsg := "hello world"

//验证签名
verifySignECC := ecc_tool.VerifySign(acceptmsg, sign, pub_key)

fmt.Println("验证结果:", index, verifySignECC, sign)

}

func test_file() {
//生成ECC密钥对文件
ecc_tool.GenerateECCKey()

//模拟发送者
//要发送的消息
msg := []byte("hello world")
//生成数字签名
rtext, stext := ecc_tool.SignECC(msg, "eccprivate.pem")

//模拟接受者
//接受到的消息
acceptmsg := []byte("hello world")
//接收到的签名
acceptrtext := rtext
acceptstext := stext
//验证签名
verifySignECC := ecc_tool.VerifySignECC(acceptmsg, acceptrtext, acceptstext, "eccpublic.pem")
fmt.Println("验证结果:", verifySignECC)
}

func main() {

for i := 0; i < 1000; i++ {
test_sign(i)
}

}

0 comments on commit d370d5b

Please sign in to comment.