-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'main' of https://github.com/lei006/go-assist into main
- Loading branch information
Showing
3 changed files
with
373 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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) | ||
} | ||
|
||
} |