Skip to content

Instantly share code, notes, and snippets.

@fahmifan
Last active June 24, 2022 03:44
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save fahmifan/8cbd3c1df6742c78cf0ed8ae60350a06 to your computer and use it in GitHub Desktop.
Save fahmifan/8cbd3c1df6742c78cf0ed8ae60350a06 to your computer and use it in GitHub Desktop.
simple AES encryption using cfb in Golang
package cryptor
import (
"crypto/aes"
"crypto/cipher"
"crypto/rand"
"encoding/hex"
"fmt"
"io"
)
type AES struct {
key []byte
}
func NewAES(key []byte) AES {
return AES{
key: key,
}
}
func (a AES) Encrypt(plainText string) (cipherText string, err error) {
ptByte := []byte(plainText)
block, err := aes.NewCipher(a.key)
if err != nil {
return "", fmt.Errorf("new cipher: %w", err)
}
ct := make([]byte, aes.BlockSize+len(ptByte))
iv := ct[:aes.BlockSize]
if _, err = io.ReadFull(rand.Reader, iv); err != nil {
return "", fmt.Errorf("make: %v", err)
}
fmt.Println("iv", hex.EncodeToString(iv))
stream := cipher.NewCFBEncrypter(block, iv)
stream.XORKeyStream(ct[aes.BlockSize:], ptByte)
return hex.EncodeToString(ct), nil
}
func (a AES) Decrypt(ct string) (plainText string, err error) {
ctByte, err := hex.DecodeString(ct)
if err != nil {
return "", fmt.Errorf("decode string: %w", err)
}
block, err := aes.NewCipher(a.key)
if err != nil {
return "", fmt.Errorf("new cipher: %w", err)
}
if len(ctByte) < aes.BlockSize {
return "", fmt.Errorf("invalid block size")
}
iv := ctByte[:aes.BlockSize]
ctByte = ctByte[aes.BlockSize:]
stream := cipher.NewCFBDecrypter(block, iv)
stream.XORKeyStream(ctByte, ctByte)
return string(ctByte), nil
}
package cryptor
import (
"strings"
"testing"
"github.com/stretchr/testify/require"
)
func TestAES(t *testing.T) {
testCases := []string{
"hello world",
"foo bar",
strings.Repeat("a really long chars", 1000),
"1",
"", // empty
}
// aes 128 byte
privateKey := strings.Repeat("S", 16)
for _, tc := range testCases {
aes := NewAES([]byte(privateKey))
ct, err := aes.Encrypt(tc)
require.NoError(t, err)
require.NotEqual(t, tc, ct)
pt, err := aes.Decrypt(ct)
require.NoError(t, err)
require.Equal(t, tc, pt)
}
}
@fahmifan
Copy link
Author

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment