From: qydysky Date: Wed, 21 Aug 2024 21:35:30 +0000 (+0800) Subject: 1 X-Git-Tag: v0.28.20240821214042~1 X-Git-Url: http://127.0.0.1:8081/?a=commitdiff_plain;h=4f5d4a7aeb83d977e26f6ae0876fdd06941e6f95;p=part%2F.git 1 --- diff --git a/crypto/Crypto.go b/crypto/Crypto.go deleted file mode 100644 index 2bf9cb3..0000000 --- a/crypto/Crypto.go +++ /dev/null @@ -1,103 +0,0 @@ -package part - -import ( - "crypto/rand" - "crypto/rsa" - "crypto/sha256" - "crypto/x509" - "encoding/pem" - "errors" - "io" - "os" -) - -type Crypto struct { - pubKey *rsa.PublicKey - priKey *rsa.PrivateKey -} - -func FileLoad(path string) (data []byte, err error) { - fileObject, e := os.OpenFile(path, os.O_RDONLY, 0644) - if e != nil { - err = e - return - } - defer fileObject.Close() - data, e = io.ReadAll(fileObject) - if e != nil { - err = e - return - } - return -} - -func (t *Crypto) PubLoad() bool { - return t.pubKey != nil -} - -func (t *Crypto) PriLoad() bool { - return t.priKey != nil -} - -func (t *Crypto) GetPKIXPubKey(pubPEMData []byte) (err error) { - block, _ := pem.Decode(pubPEMData) - if block == nil || block.Type != "PUBLIC KEY" { - err = errors.New("failed to decode PEM block containing public key") - return - } - - pubI, e := x509.ParsePKIXPublicKey(block.Bytes) - if e != nil { - err = e - return - } - t.pubKey, _ = pubI.(*rsa.PublicKey) - - return -} - -func (t *Crypto) LoadPKIXPubKey(path string) (err error) { - if d, e := FileLoad(path); e != nil { - return e - } else { - err = t.GetPKIXPubKey(d) - } - return -} - -func (t *Crypto) GetPKCS1PriKey(priPEMData []byte) (err error) { - block, _ := pem.Decode(priPEMData) - if block == nil || block.Type != "RSA PRIVATE KEY" { - err = errors.New("failed to decode PEM block containing private key") - return - } - - t.priKey, err = x509.ParsePKCS1PrivateKey(block.Bytes) - - return -} - -func (t *Crypto) LoadPKCS1PriKey(path string) (err error) { - if d, e := FileLoad(path); e != nil { - return e - } else { - err = t.GetPKCS1PriKey(d) - } - return -} - -func (t *Crypto) GetEncrypt(sourceByte []byte) (tragetByte []byte, err error) { - if t.pubKey == nil { - err = errors.New(`public key not load`) - return - } - return rsa.EncryptOAEP(sha256.New(), rand.Reader, t.pubKey, sourceByte, []byte{}) -} - -func (t *Crypto) GetDecrypt(sourceByte []byte) (tragetByte []byte, err error) { - if t.priKey == nil { - err = errors.New(`private key not load`) - return - } - return rsa.DecryptOAEP(sha256.New(), rand.Reader, t.priKey, sourceByte, []byte{}) -} diff --git a/crypto/Crypto_test.go b/crypto/Crypto_test.go deleted file mode 100644 index 2339d77..0000000 --- a/crypto/Crypto_test.go +++ /dev/null @@ -1,28 +0,0 @@ -package part - -import "testing" - -func Test_Crypto(t *testing.T){ - var k Crypto - if k.PubLoad() || k.PriLoad() {t.Error(`Keystatus not PublicKeyNoLoad`)} - { - k.LoadPKIXPubKey(`public.pem`) - } - if !k.PubLoad() || k.PriLoad() {t.Error(`Keystatus not PrivateKeyNoLoad`)} - { - d,_ := FileLoad(`private.pem`) - k.GetPKCS1PriKey(d) - } - if !k.PubLoad() || !k.PriLoad() {t.Error(`Keystatus not nil`)} - if srcs,e := k.GetEncrypt([]byte(`1we23`));e != nil { - t.Error(e) - } else if des,e := k.GetDecrypt(srcs);e != nil { - t.Error(e) - } else { - if s := string(des);s != `1we23` {t.Error(`not Match`,s)} - } - - if des,e := k.GetDecrypt([]byte(`1we23`));e == nil { - t.Error(des,e) - } -} \ No newline at end of file diff --git a/crypto/EasyCrypt.go b/crypto/EasyCrypt.go index 3502163..4906d87 100644 --- a/crypto/EasyCrypt.go +++ b/crypto/EasyCrypt.go @@ -1,56 +1,113 @@ package part import ( - "bytes" + "crypto/cipher" + "crypto/ecdh" + "crypto/rand" + "encoding/pem" "errors" - ps "github.com/qydysky/part/strings" + "golang.org/x/crypto/chacha20poly1305" ) -func Encrypt(source, pubKey []byte) ([]byte, error) { - var c Crypto - if e := c.GetPKIXPubKey(pubKey); e != nil { - return []byte{}, e - } - - key := ps.Rand(ps.UppNumber, 32) - - var g Gcm - if e := g.Init(key); e != nil { - return []byte{}, e - } +var ( + pemType = `ECDH` + ErrPemType = errors.New(`ErrPemType`) +) - if S_body, e := g.Encrypt(source); e != nil { - return []byte{}, e - } else if S_key, e := c.GetEncrypt([]byte(key)); e != nil { - return []byte{}, e +func NewKey() (pri, pub []byte, e error) { + if p1, e := ecdh.X25519().GenerateKey(rand.Reader); e != nil { + return nil, nil, e } else { - return append(S_key, append([]byte(` `), S_body...)...), nil + return pem.EncodeToMemory(&pem.Block{ + Type: pemType + ` PRIVATE KEY`, + Bytes: p1.Bytes(), + }), pem.EncodeToMemory(&pem.Block{ + Type: pemType + ` PUBLIC KEY`, + Bytes: p1.PublicKey().Bytes(), + }), nil } } -func Decrypt(source, priKey []byte) ([]byte, error) { - var loc = -1 - if loc = bytes.Index(source, []byte(` `)); loc == -1 { - return []byte{}, errors.New(`not easyCrypt type`) +func Encrypt(msg, pubKey []byte) (b []byte, e error) { + c := ecdh.X25519() + var ( + p1 *ecdh.PrivateKey + q1 *ecdh.PublicKey + q2 *ecdh.PublicKey + key []byte + aead cipher.AEAD + ) + if p1, e = c.GenerateKey(rand.Reader); e != nil { + return } + q1 = p1.PublicKey() - S_key := source[:loc] - S_body := source[loc+2:] + if pb, _ := pem.Decode(pubKey); pb.Type != pemType+` PUBLIC KEY` { + e = ErrPemType + return + } else if q2, e = ecdh.X25519().NewPublicKey(pb.Bytes); e != nil { + return + } - var c Crypto - if e := c.GetPKCS1PriKey(priKey); e != nil { - return []byte{}, e + if key, e = p1.ECDH(q2); e != nil { + return } - var g Gcm - if key, e := c.GetDecrypt(S_key); e != nil { - return []byte{}, e - } else if e := g.Init(string(key)); e != nil { - return []byte{}, e - } else if body, e := g.Decrypt(S_body); e != nil { - return []byte{}, e + if aead, e = chacha20poly1305.NewX(key); e != nil { + return + } + nonce := make([]byte, aead.NonceSize(), aead.NonceSize()+len(msg)+aead.Overhead()) + if n, err := rand.Read(nonce); err != nil { + return nil, err } else { - return body, nil + nonce = nonce[:n] } + b = q1.Bytes() + b = append(itob32(int32(len(b))), b...) + b = append(b, aead.Seal(nonce, nonce, msg, nil)...) + return +} + +func Decrypt(b, priKey []byte) (msg []byte, e error) { + var ( + q1 *ecdh.PublicKey + p2 *ecdh.PrivateKey + pemLen = int(btoi32(b[:4])) + key []byte + aead cipher.AEAD + ) + if pb, _ := pem.Decode(priKey); pb.Type != pemType+` PRIVATE KEY` { + e = ErrPemType + return + } else if p2, e = ecdh.X25519().NewPrivateKey(pb.Bytes); e != nil { + return + } else if q1, e = ecdh.X25519().NewPublicKey(b[4 : 4+pemLen]); e != nil { + return + } else if key, e = p2.ECDH(q1); e != nil { + return + } else { + if aead, e = chacha20poly1305.NewX(key); e != nil { + return + } + nonce, ciphertext := b[4+pemLen:4+pemLen+aead.NonceSize()], b[4+pemLen+aead.NonceSize():] + if msg, e = aead.Open(nil, nonce, ciphertext, nil); e != nil { + return + } + } + return +} + +func itob32(v int32) []byte { + //binary.BigEndian.PutUint32 + b := make([]byte, 4) + b[0] = byte(v >> 24) + b[1] = byte(v >> 16) + b[2] = byte(v >> 8) + b[3] = byte(v) + return b +} + +func btoi32(bu []byte) uint32 { + return uint32(bu[3]) | uint32(bu[2])<<8 | uint32(bu[1])<<16 | uint32(bu[0])<<24 } diff --git a/crypto/EasyCrypt_test.go b/crypto/EasyCrypt_test.go index 88d99ac..ac42d41 100644 --- a/crypto/EasyCrypt_test.go +++ b/crypto/EasyCrypt_test.go @@ -1,21 +1,28 @@ package part import ( + "bytes" + "crypto/rand" "testing" ) func Test_EasyCrypt(t *testing.T) { + var buf = make([]byte, 100) + if n, e := rand.Read(buf); e != nil { + t.Fatal(e) + } else { + buf = buf[:n] + } - priKey,_ := FileLoad(`private.pem`) - pubKey,_ := FileLoad(`public.pem`) - - if sc,e := Encrypt([]byte(`asdfasdfasdf`),pubKey);e != nil { - t.Error(e) - } else if s,e := Decrypt(sc,priKey);e != nil { - t.Error(e) + if pri, pub, e := NewKey(); e != nil { + t.Fatal(e) } else { - if string(s) != `asdfasdfasdf` { - t.Error(`not match`) + if b, e := Encrypt(buf, pub); e != nil { + t.Fatal(e) + } else if msg, e := Decrypt(b, pri); e != nil { + t.Fatal(e) + } else if !bytes.Equal(msg, buf) { + t.Fatal() } } -} \ No newline at end of file +}