Password Based Encryption Using AES - PBKDF2

A Go language implementation of Password-Based Key Derivation Function 2 (PBKDF2) with Advanced Encryption System (AES). Password-Based Key Derivation or PBKDF2 is a “password-strengthening algorithm” that uses a password, a variable-length salt, and an iteration count and applies a pseudorandom function to these to produce a key. It is useful when encrypting data based on a password or any other not-fully-random data.

Usage:

package main

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

func main() {
 	c := aespbkdf2.Encrypt("this is password", "testing data")
 	fmt.Println(c)
 	fmt.Println(aespbkdf2.Decrypt("this is password", c))
}

Console:

λ go run aespbkdf2.go
ae84c3655af34790-93b219ede15f83a5907cf41c-e0bcebd9d26a40ba5def944590adfb8ab14b736636bae444dfd60ac8
testing data

Code:

/**
 * AES with PBKDF2
 *
 * An implementation of Password-Based Key Derivation Function 2 (PBKDF2) 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 aespbkdf2

import (
	"bytes"
	"crypto/aes"
	"crypto/cipher"
	"crypto/rand"
	"crypto/sha256"
	"encoding/hex"
	"golang.org/x/crypto/pbkdf2"
	"strings"
)

/**
 * Key Derivation
 * @param  {[type]} passphrase string        [The Passphrase]
 * @param  {[type]} salt       []byte       ([]byte,      []byte [Sequence of bits/random data]
 * @return {[type]}            [derivationKey]
 */
func derivationKey(passphrase string, salt []byte) ([]byte, []byte) {
	if salt == nil {
		salt = make([]byte, 8)
		rand.Read(salt)
	}
	return pbkdf2.Key([]byte(passphrase), salt, 4096, 32, sha256.New), salt
}

/**
 * Encrypt Message
 * @param {[type]} passphrase       string  [The Passphrase]
 * @param {[type]} plaintext        string  [The PlainText]
 * @return {[type]} Encrypt			string  [returning object]
 */
func Encrypt(passphrase, plaintext string) string {

	key, salt := derivationKey(passphrase, nil)

	iv := make([]byte, 12)
	rand.Read(iv)

	b, _ := aes.NewCipher(key)
	aesgcm, _ := cipher.NewGCM(b)
	data := aesgcm.Seal(nil, iv, []byte(plaintext), nil)

	var buffer bytes.Buffer
	_salt := hex.EncodeToString(salt)
	_iv := hex.EncodeToString(iv)
	_data := hex.EncodeToString(data)

	buffer.WriteString(_salt)
	buffer.WriteString("-")
	buffer.WriteString(_iv)
	buffer.WriteString("-")
	buffer.WriteString(_data)

	return buffer.String()
}

/**
 * Decrypt Message
 * @param {[type]} passphrase       string  [The Passphrase]
 * @param {[type]} ciphertext       string  [The ChiperText]
 * @return {[type]} Dencrypt		string  [returning object]
 */
func Decrypt(passphrase, ciphertext string) string {

	arr := strings.Split(ciphertext, "-")

	salt, _ := hex.DecodeString(arr[0])
	iv, _ := hex.DecodeString(arr[1])
	data, _ := hex.DecodeString(arr[2])

	key, _ := derivationKey(passphrase, salt)

	b, _ := aes.NewCipher(key)
	aesgcm, _ := cipher.NewGCM(b)
	data, _ = aesgcm.Open(nil, iv, data, nil)

	return string(data)
}

https://github.com/karbhawono/aespbkdf2


592 Words

2018-05-06