I am making a custom AES-256 encryption and decryption function, i saved the functions in a package called zeus
/*
Index:
101 --> Hashing functions
102 --> Encryption functions
*/
package zeus
import (
"crypto/aes"
"crypto/cipher"
"crypto/rand"
"crypto/sha256"
"crypto/sha512"
"fmt"
"golang.org/x/crypto/bcrypt"
"io"
"log"
)
// 101 --> Hashing functions
// Takes a string, hashes it using sha256 and returns a hashed string
func SHA_256(plainText string) (hashedString string) {
bytes := []byte(plainText)
hash := sha256.Sum256(bytes)
hashedString = fmt.Sprintf("%X\n", hash)
return hashedString
}
// Takes a string, hashes it using sha512 and returns a hashed string
func SHA_512(plainText string) (hashedString string) {
bytes := []byte(plainText)
hash := sha512.Sum512(bytes)
hashedString = fmt.Sprintf("%X\n", hash)
return hashedString
}
// Takes the plainText and cost, hashes it using bcrypt and returns a
// hashed string
func Bcrypt(plainText string, cost int) (hashedString string) {
bytes := []byte(plainText)
// generate hashed string
hash, err := bcrypt.GenerateFromPassword(bytes, cost)
if err != nil {
log.Fatal(err)
}
hashedString = fmt.Sprintf("%s\n", hash)
return hashedString
}
// Checks to see if the hash matches the Plain Text
func Bcrypt_Check(hashedString string, plainText string) {
hashedString_bytes := []byte(hashedString)
plainText_bytes := []byte(plainText)
result := bcrypt.CompareHashAndPassword(hashedString_bytes, plainText_bytes)
if result != nil {
log.Fatal(result)
}
fmt.Println("Matched!")
}
// hashes the key string you enter, trim it to 32 bytes and convert it to bytes
func GenerateKey(key string) (final_key []byte) {
hashed_key := SHA_256(key)
// trimming the key to fit 32 bytes (AES-256)
trimmed_key := hashed_key[0:32]
// converting the trimmed key to bytes
final_key = []byte(trimmed_key)
return final_key
}
// 102 --> Encryption functions
// AES_256 encryption, takes plainText and a key, returns cipherText_String
func Encrypt_AES_256(plainText string, key string) (cipherText_String string) {
// convert the message (text) to bytes
plainText_bytes := []byte(plainText)
// generate key
final_key := GenerateKey(key)
// creating a new cipher block
cipher1, err := aes.NewCipher(final_key)
// checking if there is an error, if so exit the script
if err != nil {
log.Fatal(err)
}
// passing the cipher block to Galois/Counter Mode (GCM)
gcm, err := cipher.NewGCM(cipher1)
if err != nil {
log.Fatal(err)
}
// create a new byte array the size of Nonce
nonce := make([]byte, gcm.NonceSize())
// populate the byte array with a cryptographically secure random sequence
_, err = io.ReadFull(rand.Reader, nonce)
if err != nil {
log.Fatal(err)
}
// Seal encrypts and authenticates plaintext, authenticates additional data
cipherText := gcm.Seal(nonce, nonce, plainText_bytes, nil)
cipherText_String = fmt.Sprintf("%X\n", cipherText)
return cipherText_String
}
This is my main file:
package main
import (
"crypto/aes"
"crypto/cipher"
// "crypto/rand"
// "crypto/sha256"
// "crypto/sha512"
// "encoding/hex"
"fmt"
"github.com/kkaskdf/zeus"
// "golang.org/x/crypto/bcrypt"
// "io"
// "io/ioutil"
"log"
)
func Decrypt_AES_256(cipherText_String string, key string) (plainText string) {
final_key := zeus.GenerateKey(key)
cipher1, err := aes.NewCipher(final_key)
if err != nil {
log.Fatal(err)
}
gcmDecrypt, err := cipher.NewGCM(cipher1)
if err != nil {
log.Fatal(err)
}
nonceSize := gcmDecrypt.NonceSize()
cipherText_byte := []byte(cipherText_String)
if len(cipherText_byte) < nonceSize {
log.Fatal(err)
}
nonce, encryptedMessage := cipherText_byte[:nonceSize],
cipherText_byte[nonceSize:]
nonce_byte := []byte(nonce)
encryptedMessage_byte := []byte(encryptedMessage)
plaintext, err := gcmDecrypt.Open(nil, nonce_byte, encryptedMessage_byte, nil)
fmt.Println("err0")
if err != nil {
log.Fatal(err)
}
return fmt.Sprintf("%s", plaintext)
}
func main() {
// str1 := "Hi man Can"
// str2 := "Hi man Can"
// fmt.Printf("%v", zeus.SHA_256(str1))
// fmt.Printf("%v", zeus.SHA_512(str1))
// fmt.Printf("%v", zeus.Bcrypt(str1, 5))
// zeus.Bcrypt_Check(zeus.Bcrypt(str1, 5), str2)
password := "This is the password"
plainText := "Hi man Can 32 Hi man Can 23 Hi man Can"
cipherText := zeus.Encrypt_AES_256(plainText, password)
fmt.Printf("%v", cipherText)
fmt.Printf("%v", Decrypt_AES_256(cipherText, password))
}
Now when i try decrypting the cipherText , i get this output
4E4E31C4D70AC4F6F6696CB2921C208BE3124F3CBB5E73AFEE7FBB81F503034AA64EFAB3CC35784D25ED125943E835B9371BA4D3AAC9A292C00A4F256CECEF9A815B
err0
2020/12/11 00:51:49 cipher: message authentication failed
First line in the output is the encrypted text and its the output of Encrypt_AES_256()
Second line is a string i printed to detect where the error is inside the Decrypt_AES_256()
function
Third line is the output of the err here:
plaintext, err := gcmDecrypt.Open(nil, nonce_byte, encryptedMessage_byte, nil)
fmt.Println("err0")
if err != nil {
log.Fatal(err)
}
The error is in the Decrypt_AES_256()
in line
plaintext, err := gcmDecrypt.Open(nil, nonce_byte, encryptedMessage_byte, nil)
Do anyone know how to solve this problem ?
I followed the instructions from this article: