Encryption Using AES - GCM

A Go language implementation of Galois/Counter Mode (GCM) with Advanced Encryption System (AES). GCM mode is an Authenticated Encryption with Associated Data (AEAD) mode of encryption provide two security guarantees:

  • Confidentiality: The encrypted data will not leak any information about the secret plaintext data without the correct decryption key
  • Integrity: An adversary did not modify the secret plaintext data and associated data after being encrypted with AES GCM

In simpler words:

  • The encrypted information can only be read by a user who has the secret key
  • The information was not changed by anyone once it was encrypted

Usage:

package main

import (
	"fmt"
	aesgcm "github.com/karbhawono/aesgcm"
)

func main() {
    fmt.Printf("%x\n", aesgcm.Encrypt("AES256Key-32Characters1234567890", "testing 123"))
    fmt.Printf("%s\n", aesgcm.Decrypt("AES256Key-32Characters1234567890", "da269a9651869d87d3f5711074bb1652f7177db9dece2f466fb690", "13298648720762faad1b678e"))
 }

Console:

α go run main.go
{cd9ea486e8ab714e6b9b9376 456bca6efdfef24df287bf88d809be6889cbcc8bd9e5ef5d7f66ef}
{testing 123}

Code:

/**
 * AES with GCM
 *
 * An implementation of Galois/Counter Mode (GCM) with Advanced Encryption System (AES).
 *
 * Copyright (c) 2018. Aryo Karbhawono. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *    This product includes software developed by the copyright holder.
 * 4. Neither the name of the copyright holder nor the
 *    names of its contributors may be used to endorse or promote products
 *    derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER ''AS IS'' AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

package aesgcm

import (
	"crypto/aes"
	"crypto/cipher"
	"crypto/rand"
	"encoding/hex"
	"io"
)

type EncryptMessage struct {
	Nonce         []byte
	EncryptedText []byte
}
type DecryptMessage struct {
	DecryptedText string
}

/**
 * Encrypt Message
 *
 * @param {[type]} chiperkey string  [The key argument should be the AES key, either 16 or 32 bytes to select AES-128 or AES-256]
 * @param {[type]} msg       string  [The nonce]
 * @return {[type]} em       EncryptMessage [returning object]
 */
func Encrypt(chiperkey string, msg string) (em EncryptMessage) {

	key := []byte(chiperkey)

	plaintext := []byte(msg)

	block, err := aes.NewCipher(key)

	if err != nil {
		panic(err.Error())
	}

	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())
	}

	ciphertext := aesgcm.Seal(nil, nonce, plaintext, nil)

	em = EncryptMessage{
		Nonce:         nonce,
		EncryptedText: ciphertext,
	}

	return em
}

/**
 * Decrypt Message
 *
 * @param {[type]} dechiperkey   string  [The key argument should be the AES key, either 16 or 32 bytes to select AES-128 or AES-256]
 * @param {[type]} decmsg        string  [The encrypted message]
 * @param {[type]} auth          string  [The nonce]
 * @return {[type]} em           DecryptMessage [returning object]
 */
func Decrypt(dechiperkey string, decmsg string, token string) (dm DecryptMessage) {

	key := []byte(dechiperkey)

	ciphertext, _ := hex.DecodeString(decmsg)

	nonce, _ := hex.DecodeString(token)

	block, err := aes.NewCipher(key)

	if err != nil {
		panic(err.Error())
	}

	aesgcm, err := cipher.NewGCM(block)

	if err != nil {
		panic(err.Error())
	}

	plaintext, err := aesgcm.Open(nil, nonce, ciphertext, nil)

	if err != nil {
		panic(err.Error())
	}

	dm = DecryptMessage{
		DecryptedText: string(plaintext),
	}

	return dm
}

https://github.com/karbhawono/aesgcm


638 Words

2018-05-01