Encryption
AES Encryption w/ CBC mode
package main
import (
"bytes"
"crypto/aes"
"crypto/cipher"
"crypto/rand"
"encoding/base64"
"fmt"
)
func pad(raw []byte) []byte {
padding := aes.BlockSize - len(raw)%aes.BlockSize
padText := bytes.Repeat([]byte{byte(padding)}, padding)
return append(raw, padText...)
}
func unpad(raw []byte) []byte {
padCount := int(raw[len(raw)-1])
return raw[:(len(raw) - padCount)]
}
func encrypt(key []byte, raw []byte) string {
raw = pad(raw)
iv := make([]byte, aes.BlockSize)
rand.Read(iv)
encrypted := make([]byte, len(raw))
block, _ := aes.NewCipher(key)
mode := cipher.NewCBCEncrypter(block, iv)
mode.CryptBlocks(encrypted, raw)
return base64.StdEncoding.EncodeToString(append(iv, encrypted...))
}
func decrypt(key []byte, b64EncStr string) (plain []byte, err error) {
encrypted, err := base64.StdEncoding.DecodeString(b64EncStr)
if err != nil {
return nil, err
}
defer func() {
if p := recover(); p != nil {
err = fmt.Errorf("malformat: %v", p)
}
}()
iv := encrypted[:aes.BlockSize]
encrypted = encrypted[aes.BlockSize:]
block, _ := aes.NewCipher(key)
decrypted := make([]byte, len(encrypted))
mode := cipher.NewCBCDecrypter(block, iv)
mode.CryptBlocks(decrypted, encrypted)
plain = unpad(decrypted)
return unpad(decrypted), err
}
func main() {
key := []byte("12345678901234567890123456789012")
if len(key) != 32 {
fmt.Println("key length should be 32")
return
}
data := []byte("classified data")
encrypted := encrypt(key, data)
fmt.Println("Encryped:", encrypted)
decrypted, _ := decrypt(key, encrypted)
fmt.Println("Decrypted:", string(decrypted))
}