diff --git a/go.mod b/go.mod index d48399a..32690e2 100644 --- a/go.mod +++ b/go.mod @@ -9,6 +9,7 @@ require ( github.com/go-redis/redis/v8 v8.11.5 github.com/json-iterator/go v1.1.12 github.com/spf13/viper v1.14.0 + github.com/stretchr/testify v1.8.1 go.uber.org/zap v1.24.0 gopkg.in/natefinch/lumberjack.v2 v2.2.1 gorm.io/driver/mysql v1.4.5 @@ -17,6 +18,7 @@ require ( require ( github.com/cespare/xxhash/v2 v2.2.0 // indirect + github.com/davecgh/go-spew v1.1.1 // indirect github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect github.com/fsnotify/fsnotify v1.6.0 // indirect github.com/go-sql-driver/mysql v1.7.0 // indirect @@ -30,6 +32,7 @@ require ( github.com/modern-go/reflect2 v1.0.2 // indirect github.com/pelletier/go-toml v1.9.5 // indirect github.com/pelletier/go-toml/v2 v2.0.6 // indirect + github.com/pmezard/go-difflib v1.0.0 // indirect github.com/spf13/afero v1.9.3 // indirect github.com/spf13/cast v1.5.0 // indirect github.com/spf13/jwalterweatherman v1.1.0 // indirect diff --git a/mycrypto/aes.go b/mycrypto/aes.go new file mode 100644 index 0000000..1edf429 --- /dev/null +++ b/mycrypto/aes.go @@ -0,0 +1,102 @@ +package mycrypto + +import ( + "bytes" + "crypto/aes" + "crypto/cipher" + "encoding/hex" + "fmt" +) + +var ( + defaultAes256Cbc *Aes256Cbc +) + +type Aes256Cbc struct { + Iv []byte // iv向量 (key 32字节 256位) + Key []byte // 加密密钥 (iv 16字节 128位) +} + +func NewAes256Cbc(key, iv string) *Aes256Cbc { + if len(key) != 32 { + panic("密钥key长度应为32") + } + + if len(iv) != aes.BlockSize { + panic("iv长度应为16") + } + return &Aes256Cbc{ + Iv: []byte(iv), + Key: []byte(key), + } +} +func InitAes256Cbc(key, iv string) { + defaultAes256Cbc = NewAes256Cbc(key, iv) +} + +func Aes256CbcEncrypt(plainText string) (string, error) { + return defaultAes256Cbc.Encrypt(plainText) +} + +func Aes256CbcDecrypt(cipherText string) (string, error) { + return defaultAes256Cbc.Decrypt(cipherText) +} + +// Encrypt 加密 +func (a *Aes256Cbc) Encrypt(plainText string) (res string, err error) { + defer func() { + if err2 := recover(); err2 != nil { + err = fmt.Errorf("panic: %s", err2) + } + }() + + // PKCS5填充,补齐数据块 + bPlaintext := a.PKCS5Padding([]byte(plainText), aes.BlockSize) + block, err := aes.NewCipher(a.Key) + if err != nil { + return plainText, err + } + + ciphertext := make([]byte, len(bPlaintext)) + mode := cipher.NewCBCEncrypter(block, a.Iv) + mode.CryptBlocks(ciphertext, bPlaintext) + + return hex.EncodeToString(ciphertext), nil +} + +// Decrypt 解密 +func (a *Aes256Cbc) Decrypt(cipherText string) (res string, err error) { + defer func() { + if err2 := recover(); err2 != nil { + err = fmt.Errorf("panic: %s", err2) + } + }() + + block, err := aes.NewCipher(a.Key) + if err != nil { + return "", err + } + + decodeString, err := hex.DecodeString(cipherText) + if err != nil { + return "", err + } + + mode := cipher.NewCBCDecrypter(block, a.Iv) + mode.CryptBlocks(decodeString, decodeString) + + // 移除多余填充的补充位 + return string(a.PKCS5UnPadding(decodeString)), nil +} + +func (a *Aes256Cbc) PKCS5Padding(ciphertext []byte, blockSize int) []byte { + padding := blockSize - len(ciphertext)%blockSize + padtext := bytes.Repeat([]byte{byte(padding)}, padding) + return append(ciphertext, padtext...) +} + +func (a *Aes256Cbc) PKCS5UnPadding(src []byte) []byte { + length := len(src) + unpadding := int(src[length-1]) + return src[:(length - unpadding)] +} diff --git a/mycrypto/aes_test.go b/mycrypto/aes_test.go new file mode 100644 index 0000000..6255fa3 --- /dev/null +++ b/mycrypto/aes_test.go @@ -0,0 +1,83 @@ +package mycrypto + +import ( + "fmt" + "github.com/stretchr/testify/assert" + "testing" +) + +func TestAes256Cbc(t *testing.T) { + key := "iYWKp8yz11iAzdSrGdYAhaW82Kdw209c" + iv := "QsHZn2hacbZ5A7PT" + InitAes256Cbc(key, iv) + + str := "1234567890111213" + encrypt, err := Aes256CbcEncrypt(str) + if err != nil { + fmt.Println(err) + return + } + fmt.Printf("---%+v---\n", encrypt) + + decrypt, err := Aes256CbcDecrypt(encrypt) + if err != nil { + fmt.Println(err) + return + } + + as := assert.New(t) + fmt.Printf("%+v\n", as.Equal(str, decrypt)) + fmt.Printf("%s %s\n", str, decrypt) + +} + +func BenchmarkAes256Cbc(b *testing.B) { + key := "7zlx6MoTL76B9BiYuO4nytGBUk0HnSJ1" + iv := "1234567890123456" + InitAes256Cbc(key, iv) + + for i := 0; i < b.N; i++ { + str := fmt.Sprintf("440123456789%d10111213", i) + encrypt, err := Aes256CbcEncrypt(str) + if err != nil { + fmt.Println(err) + return + } + //fmt.Printf("%+v%s\n", encrypt, "---") + + _, err = Aes256CbcDecrypt(encrypt) + if err != nil { + fmt.Println(err) + return + } + + } +} + +func BenchmarkAes256CbcCheck(b *testing.B) { + key := "iYWKp8yz11iAzdSrGdYAhaW82Kdw209c" + iv := "QsHZn2hacbZ5A7PT" + InitAes256Cbc(key, iv) + as := assert.New(b) + + for i := 0; i < b.N; i++ { + str := fmt.Sprintf("440123456789%d10111213", i) + encrypt, err := Aes256CbcEncrypt(str) + if err != nil { + fmt.Println(err) + return + } + //fmt.Printf("%+v%s\n", encrypt, "---") + + decrypt, err := Aes256CbcDecrypt(encrypt) + if err != nil { + fmt.Println(err) + return + } + + if !as.Equal(str, decrypt) { + b.Fail() + } + + } +} diff --git a/mycrypto/hash.go b/mycrypto/hash.go new file mode 100644 index 0000000..48d8769 --- /dev/null +++ b/mycrypto/hash.go @@ -0,0 +1,20 @@ +package mycrypto + +import ( + "crypto/md5" + "crypto/sha1" + "encoding/hex" +) + +func Md5(str string) string { + h := md5.New() + h.Write([]byte(str)) + + return hex.EncodeToString(h.Sum(nil)) +} + +func Sha1(str string) string { + h := sha1.New() + h.Write([]byte(str)) + return hex.EncodeToString(h.Sum(nil)) +}