Skip to content

Instantly share code, notes, and snippets.

@syed
Last active December 12, 2022 10:11
Show Gist options
  • Save syed/cce07bdc456d9ca5678b to your computer and use it in GitHub Desktop.
Save syed/cce07bdc456d9ca5678b to your computer and use it in GitHub Desktop.
This simple program is to demonstrate encryption and decryption in golang using AES CBC with PKCS5Padding
package main
import (
"bytes"
"crypto/aes"
"crypto/cipher"
b64 "encoding/base64"
"errors"
"fmt"
"log"
)
var base64EncodedKeyBytes = "kV9Ld-X4rKlTQF4ZJwyn9A"
var base64EncodedIvBytes = "PCb_WQYrUgbahQeqDEkuUw"
func main() {
key, err1 := b64.RawURLEncoding.DecodeString(base64EncodedKeyBytes)
iv, err2 := b64.RawURLEncoding.DecodeString(base64EncodedIvBytes)
if err1 != nil || err2 != nil {
log.Fatal("Error decoding key/iv")
}
//plaintext := []byte("some really really really long plaintext")
//plaintext := []byte("testtesttesttest")
plaintext := []byte("test")
fmt.Printf("plaintext: %s\n", plaintext)
ciphertext, err := encrypt(key, iv, plaintext)
if err != nil {
log.Fatal(err)
}
fmt.Printf("encrypted: %s\n", ciphertext)
decrypted, err := decrypt(key, iv, ciphertext)
if err != nil {
log.Fatal(err)
}
fmt.Printf("decrypted: %s\n", decrypted)
}
func encrypt(key, iv, text []byte) (string, error) {
block, err := aes.NewCipher(key)
if err != nil {
return "", err
}
b := text
b = PKCS5Padding(b, aes.BlockSize, len(text))
ciphertext := make([]byte, len(b))
mode := cipher.NewCBCEncrypter(block, iv)
mode.CryptBlocks(ciphertext, b)
return b64.RawURLEncoding.EncodeToString(ciphertext), nil
}
func decrypt(key []byte, iv []byte, encText string) ([]byte, error) {
text, _ := b64.RawURLEncoding.DecodeString(encText)
block, err := aes.NewCipher(key)
if err != nil {
return nil, err
}
if len(text) < aes.BlockSize {
return nil, errors.New("ciphertext too short")
}
decrypted := make([]byte, len(text))
mode := cipher.NewCBCDecrypter(block, iv)
mode.CryptBlocks(decrypted, text)
return PKCS5UnPadding(decrypted), nil
}
func PKCS5Padding(ciphertext []byte, blockSize int, after int) []byte {
padding := (blockSize - len(ciphertext)%blockSize)
padtext := bytes.Repeat([]byte{byte(padding)}, padding)
return append(ciphertext, padtext...)
}
func PKCS5UnPadding(src []byte) []byte {
length := len(src)
unpadding := int(src[length-1])
return src[:(length - unpadding)]
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment