Skip to content

Instantly share code, notes, and snippets.

@dakait
Last active December 18, 2023 20:29
Show Gist options
  • Save dakait/8f78312997611617f26430d07ffe5dc3 to your computer and use it in GitHub Desktop.
Save dakait/8f78312997611617f26430d07ffe5dc3 to your computer and use it in GitHub Desktop.
AES-256 GCM Encryption/Decryption Example in Golang
package secure
import (
"crypto/aes"
"crypto/cipher"
"encoding/hex"
"fmt"
"crypto/sha512"
)
func CipherMydata(text string) {
//cipher key
dStr, _ := hex.DecodeString("310bc65ed2bfd049a3877465ebd547210a492db4edf03e9506a3f942135d55e4")
plaintext := []byte(text)
//*******************************
/*This step can be removed or modified. I'm using sha512 to increase length of
key and use part of hashed key as nonce and newKey. You can think of some other way or
just remove sha512 and use your custom nonce and key as it is. The reason I'm doing this
is to make nonce dynamic since key is known to both the parties.
*/
hasher := sha512.New()
hasher.Write(dStr)
out := hex.EncodeToString(hasher.Sum(nil))
newKey, _ := hex.DecodeString(out[:64])
nonce, _ := hex.DecodeString(out[64:(64+24)])
//*******************************
aData, _ := hex.DecodeString("03c128d8a500d78e0ee0f8ab4662584b")
fmt.Println("Adata:\t 03c128d8a500d78e0ee0f8ab4662584b")
block, err := aes.NewCipher(newKey)
if err != nil {
panic(err.Error())
}
aesgcm, err := cipher.NewGCM(block)
if err != nil {
panic(err.Error())
}
cipherText := aesgcm.Seal(nil, nonce, plaintext, aData)
fmt.Printf("Ciphered text:\t %x\n", cipherText)
}
package secure
import (
"crypto/aes"
"crypto/cipher"
"encoding/hex"
"fmt"
"crypto/sha512"
)
func DecipherMydata(adata, data string) {
dStr, _ := hex.DecodeString("310bc65ed2bfd049a3877465ebd547210a492db4edf03e9506a3f942135d55e4")
//*******************************
hasher := sha512.New()
hasher.Write(dStr)
out := hex.EncodeToString(hasher.Sum(nil))
newKey, _ := hex.DecodeString(out[:64])
nonce, _ := hex.DecodeString(out[64:(64+24)])
//*******************************
aData, _ := hex.DecodeString(adata)
block, err := aes.NewCipher(newKey)
if err != nil {
panic(err.Error())
}
aesgcm, err := cipher.NewGCM(block)
if err != nil {
panic(err.Error())
}
cipherText, _ := hex.DecodeString(data)
output, _ := aesgcm.Open(nil, nonce, cipherText, aData)
fmt.Println("Data:\t ", string(output))
}
//Applying AES-256 GCM
package main
import "secure" //check import according to GOPATH
func main() {
//cipher data
text := "password"
secure.CipherMydata(text)
/*
Output:
Adata: 03c128d8a500d78e0ee0f8ab4662584b
Ciphered text: 50b18db2616d85b9165ea08d6bfa1344f6bfa4c31c05730d
*/
//decrypting data
secure.DecipherMydata("03c128d8a500d78e0ee0f8ab4662584b", "50b18db2616d85b9165ea08d6bfa1344f6bfa4c31c05730d")
/*
Output :
Data: password
*/
}
@joonas-fi
Copy link

This code looks really dangerous, and I would advise anyone against using it. I don't have time to analyze it thoroughly, but these things stick out:

  • You're doing something clever here, and you should never be clever with crypto. Crypto is easy to get wrong unless you have years of experience at it
  • You're not checking errors on sha512.Write()

@cjbearman
Copy link

I found this whilst looking for an example of AES256-GCM in golang. I agree that this looks really dangerous and should not be used.

My reasoning is that the key and nonce are both derived from a SHA hash of the "key". Whilst on the surface that looks pretty sound, in reality it means the nonce will be the same for every encryption - and that's a big no no. The nonce must be unique for every encryption using a given key.

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