67 lines
1.5 KiB
Go
67 lines
1.5 KiB
Go
package crypto
|
|
|
|
import (
|
|
"bytes"
|
|
"crypto/aes"
|
|
"crypto/cipher"
|
|
"fmt"
|
|
)
|
|
|
|
func aesEncrypt(key, iv, plaintext []byte) ([]byte, error) {
|
|
block, err := aes.NewCipher(key)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
plaintext = pkcs7Pad(plaintext, aes.BlockSize)
|
|
ciphertext := make([]byte, len(plaintext))
|
|
mode := cipher.NewCBCEncrypter(block, iv)
|
|
mode.CryptBlocks(ciphertext, plaintext)
|
|
return ciphertext, nil
|
|
}
|
|
|
|
func aesDecrypt(key, iv, ciphertext []byte) ([]byte, error) {
|
|
block, err := aes.NewCipher(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")
|
|
}
|
|
|
|
plaintext := make([]byte, len(ciphertext))
|
|
mode := cipher.NewCBCDecrypter(block, iv)
|
|
mode.CryptBlocks(plaintext, ciphertext)
|
|
|
|
plaintext, err = pkcs7Unpad(plaintext)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return plaintext, nil
|
|
}
|
|
|
|
func pkcs7Pad(data []byte, blockSize int) []byte {
|
|
padding := blockSize - (len(data) % blockSize)
|
|
padText := bytes.Repeat([]byte{byte(padding)}, padding)
|
|
return append(data, padText...)
|
|
}
|
|
|
|
func pkcs7Unpad(data []byte) ([]byte, error) {
|
|
length := len(data)
|
|
if length == 0 {
|
|
return nil, fmt.Errorf("data is empty")
|
|
}
|
|
padding := int(data[length-1])
|
|
if padding == 0 || padding > aes.BlockSize || length < aes.BlockSize {
|
|
return nil, fmt.Errorf("invalid padding")
|
|
}
|
|
paddingStart := length - padding
|
|
for i := paddingStart; i < length; i++ {
|
|
if data[i] != byte(padding) {
|
|
return nil, fmt.Errorf("invalid padding")
|
|
}
|
|
}
|
|
return data[:paddingStart], nil
|
|
}
|