package main
import (
"bytes"
"crypto/aes"
"encoding/base64"
"errors"
"reflect"
)
func EncryptToBase64(passwd []byte, data []byte) (string, error) {
secret, err := Encrypt(passwd, data)
if err != nil {
return "", err
}
return base64.StdEncoding.EncodeToString(secret), nil
}
func DecryptFromBase64(passwd []byte, data string) ([]byte, error) {
rawData, err := base64.StdEncoding.DecodeString(data)
if err != nil {
return nil, err
}
return Decrypt(passwd, rawData)
}
func Encrypt(key []byte, text []byte) ([]byte, error) {
c, err := aes.NewCipher(PasswdPadding(key))
if err != nil {
return nil, err
}
paddingText := PKCS7Padding(text)
cipherText := make([]byte, len(paddingText))
for st, ed := 0, aes.BlockSize; ed <= len(paddingText); st, ed = st+aes.BlockSize, ed+aes.BlockSize {
c.Encrypt(cipherText[st:ed], paddingText[st:ed])
}
return cipherText, nil
}
func Decrypt(key []byte, cipherText []byte) ([]byte, error) {
c, err := aes.NewCipher(PasswdPadding(key))
if err != nil {
return nil, err
}
paddingText := make([]byte, len(cipherText))
for st, ed := 0, aes.BlockSize; ed <= len(paddingText); st, ed = st+aes.BlockSize, ed+aes.BlockSize {
c.Decrypt(paddingText[st:ed], cipherText[st:ed])
}
return PKCS7UnPadding(paddingText)
}
func PasswdPadding(key []byte) []byte {
ret := make([]byte, 32)
copy(ret, key)
return ret
}
func PKCS7Padding(text []byte) []byte {
padding := 16 - len(text)%16
paddingText := bytes.Repeat([]byte{byte(padding)}, padding)
return append(text, paddingText...)
}
func PKCS7UnPadding(text []byte) ([]byte, error) {
length := len(text)
if length < 16 || text[length-1] > 16 {
return nil, errors.New("invalid text length")
}
unPadding := int(text[length-1])
ed := length - unPadding
return text[:ed], nil
}
func main() {
key := []byte("0123456789abcdeffafff")
text := []byte("0123456789abcdef0123456789abcdef")
encText, err := EncryptToBase64(key, text)
if err != nil {
panic(err)
}
decText, err := DecryptFromBase64(key, encText)
if err != nil {
panic(err)
}
println("秘钥:", string(key))
println("原文:", string(text))
println("密文:", string(encText))
println("解密:", string(decText))
println("原文与解密后文字是否相等:", reflect.DeepEqual(text, decText))
}
秘钥: 0123456789abcdeffafff
原文: 0123456789abcdef0123456789abcdef
密文: lwYlRgu+3JGWLJmLlkO4FZcGJUYLvtyRliyZi5ZDuBUgV7at5VdidSdAAj40elq0
解密: 0123456789abcdef0123456789abcdef
原文与解密后文字是否相等: true