Last active
August 27, 2024 10:50
-
-
Save fracasula/38aa1a4e7481f9cedfa78a0cdd5f1865 to your computer and use it in GitHub Desktop.
A simple example with Golang that uses AES-128 to encrypt and decrypt messages.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package mycrypto | |
import ( | |
"crypto/aes" | |
"crypto/cipher" | |
"crypto/rand" | |
"encoding/base64" | |
"io" | |
"time" | |
) | |
func EncryptMessage(key []byte, message string) (string, error) { | |
byteMsg := []byte(message) | |
block, err := aes.NewCipher(key) | |
if err != nil { | |
return "", fmt.Errorf("could not create new cipher: %v", err) | |
} | |
cipherText := make([]byte, aes.BlockSize+len(byteMsg)) | |
iv := cipherText[:aes.BlockSize] | |
if _, err = io.ReadFull(rand.Reader, iv); err != nil { | |
return "", fmt.Errorf("could not encrypt: %v", err) | |
} | |
stream := cipher.NewCFBEncrypter(block, iv) | |
stream.XORKeyStream(cipherText[aes.BlockSize:], byteMsg) | |
return base64.StdEncoding.EncodeToString(cipherText), nil | |
} | |
func DecryptMessage(key []byte, message string) (string, error) { | |
cipherText, err := base64.StdEncoding.DecodeString(message) | |
if err != nil { | |
return "", fmt.Errorf("could not base64 decode: %v", err) | |
} | |
block, err := aes.NewCipher(key) | |
if err != nil { | |
return "", fmt.Errorf("could not create new cipher: %v", err) | |
} | |
if len(cipherText) < aes.BlockSize { | |
return "", fmt.Errorf("invalid ciphertext block size") | |
} | |
iv := cipherText[:aes.BlockSize] | |
cipherText = cipherText[aes.BlockSize:] | |
stream := cipher.NewCFBDecrypter(block, iv) | |
stream.XORKeyStream(cipherText, cipherText) | |
return string(cipherText), nil | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package mycrypto | |
import ( | |
"testing" | |
"github.com/stretchr/testify/require" | |
) | |
const isBase64 = "^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=|[A-Za-z0-9+/]{4})$" | |
func TestEncryptDecryptMessage(t *testing.T) { | |
key := []byte("0123456789abcdef") // must be of 16 bytes for this example to work | |
message := "Lorem ipsum dolor sit amet" | |
encrypted, err := EncryptMessage(key, message) | |
require.Nil(t, err) | |
require.Regexp(t, isBase64, encrypted) | |
decrypted, err := DecryptMessage(key, encrypted) | |
require.Nil(t, err) | |
require.Equal(t, message, decrypted) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Bro thank you, I've been struggling with understanding the ciphertext block size and this code has cleared it out for me