+++ /dev/null
-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{})
-}
+++ /dev/null
-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
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
}
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
+}