|
@@ -0,0 +1,76 @@
|
|
|
+package encryption
|
|
|
+
|
|
|
+import (
|
|
|
+ "bytes"
|
|
|
+ "crypto/aes"
|
|
|
+ "crypto/cipher"
|
|
|
+ "fmt"
|
|
|
+)
|
|
|
+
|
|
|
+type AesCBCWithPadding struct {
|
|
|
+ key []byte
|
|
|
+ iv []byte
|
|
|
+}
|
|
|
+
|
|
|
+func NewAesCBCWithPadding(key, iv []byte) *AesCBCWithPadding {
|
|
|
+ return &AesCBCWithPadding{
|
|
|
+ key: key,
|
|
|
+ iv: iv,
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+// ZeroPadding 填充(填充0x00到块大小)
|
|
|
+func zeroPad(data []byte, blockSize int) []byte {
|
|
|
+ padding := blockSize - len(data)%blockSize
|
|
|
+ padText := bytes.Repeat([]byte{0}, padding)
|
|
|
+ return append(data, padText...)
|
|
|
+}
|
|
|
+
|
|
|
+// ZeroUnPadding 去除填充的0x00
|
|
|
+func zeroUnPad(data []byte) []byte {
|
|
|
+ return bytes.TrimRightFunc(data, func(r rune) bool {
|
|
|
+ return r == rune(0)
|
|
|
+ })
|
|
|
+}
|
|
|
+
|
|
|
+// AES加密函数
|
|
|
+func (a *AesCBCWithPadding) Encrypt(plaintext []byte) ([]byte, error) {
|
|
|
+ block, err := aes.NewCipher(a.key)
|
|
|
+ if err != nil {
|
|
|
+ return nil, err
|
|
|
+ }
|
|
|
+
|
|
|
+ //if len(plaintext)%aes.BlockSize != 0 {
|
|
|
+ // return nil, fmt.Errorf("plaintext is not a multiple of the block size")
|
|
|
+ //}
|
|
|
+
|
|
|
+ plaintext = zeroPad(plaintext, aes.BlockSize)
|
|
|
+
|
|
|
+ ciphertext := make([]byte, aes.BlockSize+len(plaintext))
|
|
|
+ copy(ciphertext[:aes.BlockSize], a.iv)
|
|
|
+ mode := cipher.NewCBCEncrypter(block, a.iv)
|
|
|
+ mode.CryptBlocks(ciphertext, plaintext)
|
|
|
+
|
|
|
+ return ciphertext, nil
|
|
|
+}
|
|
|
+
|
|
|
+// AES解密函数
|
|
|
+func (a *AesCBCWithPadding) Decrypt(ciphertext []byte) ([]byte, error) {
|
|
|
+ block, err := aes.NewCipher(a.key)
|
|
|
+ if err != nil {
|
|
|
+ return nil, err
|
|
|
+ }
|
|
|
+
|
|
|
+ if len(ciphertext)%aes.BlockSize != 0 {
|
|
|
+ return nil, fmt.Errorf("ciphertext is not a multiple of the block size")
|
|
|
+ }
|
|
|
+
|
|
|
+ decrypted := make([]byte, len(ciphertext))
|
|
|
+ copy(decrypted, ciphertext)
|
|
|
+
|
|
|
+ mode := cipher.NewCBCDecrypter(block, a.iv)
|
|
|
+ mode.CryptBlocks(decrypted, ciphertext)
|
|
|
+
|
|
|
+ plaintext := zeroUnPad(decrypted)
|
|
|
+ return plaintext, nil
|
|
|
+}
|