|
@@ -0,0 +1,233 @@
|
|
|
+package util
|
|
|
+
|
|
|
+import (
|
|
|
+ "bytes"
|
|
|
+ "crypto/aes"
|
|
|
+ "crypto/cipher"
|
|
|
+ "crypto/rand"
|
|
|
+ "crypto/rsa"
|
|
|
+ "crypto/x509"
|
|
|
+ "encoding/binary"
|
|
|
+ "encoding/json"
|
|
|
+ "fmt"
|
|
|
+ "io"
|
|
|
+)
|
|
|
+
|
|
|
+// Signer interface
|
|
|
+type Signer interface {
|
|
|
+ GetPrivateKey() *rsa.PrivateKey
|
|
|
+}
|
|
|
+
|
|
|
+// Check error function
|
|
|
+func Check(err error, args ...interface{}) {
|
|
|
+ if err != nil {
|
|
|
+ if len(args) == 0 {
|
|
|
+ panic(err)
|
|
|
+ } else {
|
|
|
+ format := args[0].(string)
|
|
|
+ args[0] = err
|
|
|
+ panic(fmt.Errorf(format, append(args[1:], err)...))
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+// Uint64ToBytes func
|
|
|
+func Uint64ToBytes(v uint64) []byte {
|
|
|
+ bb := make([]byte, 8)
|
|
|
+ binary.LittleEndian.PutUint64(bb, v)
|
|
|
+ return bb
|
|
|
+}
|
|
|
+
|
|
|
+// UintToBytes func
|
|
|
+func UintToBytes(v uint) []byte {
|
|
|
+ bb := make([]byte, 4)
|
|
|
+ binary.LittleEndian.PutUint32(bb, uint32(v))
|
|
|
+ return bb
|
|
|
+}
|
|
|
+
|
|
|
+// KeyRSA func
|
|
|
+func KeyRSA() *rsa.PrivateKey {
|
|
|
+ var privateKey *rsa.PrivateKey
|
|
|
+ var err error
|
|
|
+
|
|
|
+ if privateKey, err = rsa.GenerateKey(rand.Reader, 2048); err != nil {
|
|
|
+ panic(err)
|
|
|
+ }
|
|
|
+
|
|
|
+ return privateKey
|
|
|
+}
|
|
|
+
|
|
|
+// MarshalPublicKey func
|
|
|
+func MarshalPublicKey(key *rsa.PublicKey) []byte {
|
|
|
+ if data, err := x509.MarshalPKIXPublicKey(key); err != nil {
|
|
|
+ panic(err)
|
|
|
+ } else {
|
|
|
+ return data
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+// UnmarshalPublicKey func
|
|
|
+func UnmarshalPublicKey(key []byte) *rsa.PublicKey {
|
|
|
+ var kk interface{}
|
|
|
+ var err error
|
|
|
+ if kk, err = x509.ParsePKIXPublicKey(key); err != nil {
|
|
|
+ panic(err)
|
|
|
+ }
|
|
|
+ return kk.(*rsa.PublicKey)
|
|
|
+}
|
|
|
+
|
|
|
+// MarshalPrivateKey func
|
|
|
+func MarshalPrivateKey(key *rsa.PrivateKey) []byte {
|
|
|
+ return x509.MarshalPKCS1PrivateKey(key)
|
|
|
+}
|
|
|
+
|
|
|
+// UnmarshalPrivateKey func
|
|
|
+func UnmarshalPrivateKey(key []byte) *rsa.PrivateKey {
|
|
|
+ var kk *rsa.PrivateKey
|
|
|
+ var err error
|
|
|
+ if kk, err = x509.ParsePKCS1PrivateKey(key); err != nil {
|
|
|
+ panic(err)
|
|
|
+ }
|
|
|
+ return kk
|
|
|
+}
|
|
|
+
|
|
|
+// JSONMarshal func
|
|
|
+func JSONMarshal(w io.Writer, v interface{}) {
|
|
|
+ if d, err := json.Marshal(v); err == nil {
|
|
|
+ w.Write(d)
|
|
|
+ } else {
|
|
|
+ panic(err)
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+// JSONUnmarshal func
|
|
|
+func JSONUnmarshal(b []byte, v interface{}) interface{} {
|
|
|
+ if err := json.Unmarshal(b, v); err != nil {
|
|
|
+ panic(err)
|
|
|
+ }
|
|
|
+ return v
|
|
|
+}
|
|
|
+
|
|
|
+// PrivateKey func
|
|
|
+func PrivateKey() *rsa.PrivateKey {
|
|
|
+ var err error
|
|
|
+ var privateKey *rsa.PrivateKey
|
|
|
+
|
|
|
+ if privateKey, err = rsa.GenerateKey(rand.Reader, 2048); err != nil {
|
|
|
+ panic(err)
|
|
|
+ }
|
|
|
+
|
|
|
+ return privateKey
|
|
|
+}
|
|
|
+
|
|
|
+// EncryptRSA func
|
|
|
+func EncryptRSA(key *rsa.PublicKey, data []byte) []byte {
|
|
|
+ var err error
|
|
|
+ klen := key.N.BitLen()/8 - 11
|
|
|
+ if len(data) <= klen {
|
|
|
+ var bb []byte
|
|
|
+ if bb, err = rsa.EncryptPKCS1v15(rand.Reader, key, data); err != nil {
|
|
|
+ panic(err)
|
|
|
+ }
|
|
|
+ return bb
|
|
|
+ }
|
|
|
+ var buf bytes.Buffer
|
|
|
+ var bb []byte
|
|
|
+ for i, w, r := 0, 0, len(data); r > 0; i, r = i+w, r-w {
|
|
|
+ if r <= klen {
|
|
|
+ if bb, err = rsa.EncryptPKCS1v15(rand.Reader, key, data[i:]); err != nil {
|
|
|
+ panic(err)
|
|
|
+ }
|
|
|
+ buf.Write(bb)
|
|
|
+ w = r
|
|
|
+ } else {
|
|
|
+ if bb, err = rsa.EncryptPKCS1v15(rand.Reader, key, data[i:i+klen]); err != nil {
|
|
|
+ panic(err)
|
|
|
+ }
|
|
|
+ buf.Write(bb)
|
|
|
+ w = klen
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return buf.Bytes()
|
|
|
+}
|
|
|
+
|
|
|
+// DecryptRSA func
|
|
|
+func DecryptRSA(key *rsa.PrivateKey, data []byte) []byte {
|
|
|
+ var err error
|
|
|
+ klen := key.N.BitLen() / 8
|
|
|
+ if len(data) <= klen {
|
|
|
+ var bb []byte
|
|
|
+ if bb, err = rsa.DecryptPKCS1v15(rand.Reader, key, data); err != nil {
|
|
|
+ panic(err)
|
|
|
+ }
|
|
|
+ return bb
|
|
|
+ }
|
|
|
+ var buf bytes.Buffer
|
|
|
+ var bb []byte
|
|
|
+ for i, w, r := 0, 0, len(data); r > 0; i, r = i+w, r-w {
|
|
|
+ if r <= klen {
|
|
|
+ if bb, err = rsa.DecryptPKCS1v15(rand.Reader, key, data[i:]); err != nil {
|
|
|
+ panic(err)
|
|
|
+ }
|
|
|
+ buf.Write(bb)
|
|
|
+ w = r
|
|
|
+ } else {
|
|
|
+ if bb, err = rsa.DecryptPKCS1v15(rand.Reader, key, data[i:i+klen]); err != nil {
|
|
|
+ panic(err)
|
|
|
+ }
|
|
|
+ buf.Write(bb)
|
|
|
+ w = klen
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return buf.Bytes()
|
|
|
+}
|
|
|
+
|
|
|
+// KeyAES func
|
|
|
+func KeyAES() []byte {
|
|
|
+ var err error
|
|
|
+ var key = make([]byte, 32)
|
|
|
+ if _, err = rand.Read(key); err != nil {
|
|
|
+ panic(fmt.Errorf("Error generate aes key\n\n%+v", err))
|
|
|
+ }
|
|
|
+ return key
|
|
|
+}
|
|
|
+
|
|
|
+// EncryptAES func
|
|
|
+func EncryptAES(key, data []byte) []byte {
|
|
|
+ block, err := aes.NewCipher(key)
|
|
|
+ if err != nil {
|
|
|
+ panic(err)
|
|
|
+ }
|
|
|
+
|
|
|
+ ciphertext := make([]byte, aes.BlockSize+len(data))
|
|
|
+ iv := ciphertext[:aes.BlockSize]
|
|
|
+ if _, err := io.ReadFull(rand.Reader, iv); err != nil {
|
|
|
+ panic(err)
|
|
|
+ }
|
|
|
+
|
|
|
+ stream := cipher.NewCFBEncrypter(block, iv)
|
|
|
+ stream.XORKeyStream(ciphertext[aes.BlockSize:], data)
|
|
|
+
|
|
|
+ return ciphertext
|
|
|
+}
|
|
|
+
|
|
|
+// DecryptAES func
|
|
|
+func DecryptAES(key, ciphertext []byte) []byte {
|
|
|
+ block, err := aes.NewCipher(key)
|
|
|
+ if err != nil {
|
|
|
+ panic(fmt.Errorf("Error creating new block cipher\n%v\n", err))
|
|
|
+ }
|
|
|
+
|
|
|
+ if len(ciphertext) < aes.BlockSize {
|
|
|
+ panic(fmt.Errorf("ciphertext too short"))
|
|
|
+ }
|
|
|
+ iv := ciphertext[:aes.BlockSize]
|
|
|
+ ciphertext = ciphertext[aes.BlockSize:]
|
|
|
+
|
|
|
+ stream := cipher.NewCFBDecrypter(block, iv)
|
|
|
+
|
|
|
+ // XORKeyStream can work in-place if the two arguments are the same.
|
|
|
+ stream.XORKeyStream(ciphertext, ciphertext)
|
|
|
+
|
|
|
+ return ciphertext
|
|
|
+}
|