Last active
February 12, 2023 22:36
-
-
Save squashbrain/db57f99b41ee5443587e7589ff29c669 to your computer and use it in GitHub Desktop.
AES GCM Encryption/Decryption
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 main | |
import ( | |
"crypto/aes" | |
"crypto/cipher" | |
"crypto/rand" | |
"fmt" | |
"io" | |
) | |
/* | |
This snippet was derived with help from reading,testing and understanding this: | |
https://gist.github.com/kkirsche/e28da6754c39d5e7ea10 | |
*/ | |
func aesEncrypt(key []byte, plaintext string) (nonce []byte, cipherstr []byte) { | |
bplaintext := []byte(plaintext) | |
block, err := aes.NewCipher(key) | |
if err != nil { | |
panic(err.Error()) | |
} | |
// Never use more than 2^32 random nonces with a given key because of the risk of a repeat. | |
nonce = make([]byte, 12) | |
if _, err := io.ReadFull(rand.Reader, nonce); err != nil { | |
panic(err.Error()) | |
} | |
aesgcm, err := cipher.NewGCM(block) | |
if err != nil { | |
panic(err.Error()) | |
} | |
// encrypt an prepend the nonce to the ciphertext before returning it | |
ciphertext := aesgcm.Seal(nonce, nonce, bplaintext, nil) | |
return nonce, ciphertext | |
} | |
func aesDecrypt(key []byte, ciphertext []byte) []byte { | |
block, err := aes.NewCipher(key) | |
if err != nil { | |
panic(err.Error()) | |
} | |
aesgcm, err := cipher.NewGCM(block) | |
if err != nil { | |
panic(err.Error()) | |
} | |
// the nonce is prepended to the cipher text so we need to make sure it is still there and length matches up | |
nonceSize := aesgcm.NonceSize() | |
if len(ciphertext) < nonceSize { | |
panic(err.Error()) | |
} | |
// now we split the nonce from the ciptertext | |
nonce, ciphertext := ciphertext[:nonceSize], ciphertext[nonceSize:] | |
plaintext, err := aesgcm.Open(nil, nonce, ciphertext, nil) | |
if err != nil { | |
panic(err.Error()) | |
} | |
return plaintext | |
} | |
func main() { | |
// plain text that needs to be encrypted | |
plaintext := "This needs to be encrypted" | |
/* | |
The key length you provide determines the AES block size used during encryption/decryption | |
16 byte key = AES-128 | |
24 byte key = AES-192 | |
32 byte key = AES-256 | |
*/ | |
// AES-128 key | |
//key := []byte("AES256Key-16Char") | |
// AES-192 key | |
//key := []byte("AES256Key-24Characters12") | |
// AES-256 key | |
key := []byte("AES256Key-32Characters1234567890") | |
// just used to display the mode based on the key size | |
var aesmode string | |
switch len(key) { | |
case 16: | |
aesmode = "AES-128 GCM" | |
case 24: | |
aesmode = "AES-192 GCM" | |
case 32: | |
aesmode = "AES-256 GCM" | |
} | |
// AES-XXX-GCM encryption | |
nonce, cipherstr := aesEncrypt(key, plaintext) | |
fmt.Printf("\nEncrypting using [%s]:\n", aesmode) | |
fmt.Printf(" Key In = %s\n", string(key)) | |
fmt.Printf(" Plain Text In = %s\n", plaintext) | |
fmt.Printf(" Cipher Out = %x\n", cipherstr) | |
fmt.Printf(" Nonce Out = %x\n\n", nonce) | |
// AES-XXX-GCM decryption | |
bplaintext := aesDecrypt(key, cipherstr) | |
fmt.Printf("Decrypting using [%s]:\n", aesmode) | |
fmt.Printf(" Key In = %s\n", string(key)) | |
fmt.Printf(" Cipher In = %x\n", cipherstr) | |
fmt.Printf(" Plain Text Out = %s\n", string(bplaintext)) | |
fmt.Print("\n\n\n") | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment