crypto

package module
v0.0.0-...-0599e33 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 4, 2020 License: MIT Imports: 8 Imported by: 0

README

Build Status Documentation

Crypto | Geoff Ford

An example of use is available in GoDocs.

Installing and building the library

This project requires Go 1.14.2

To use this package in your own code, install it using go get:

go get github.com/gford1000-go/crypto

Then, you can include it in your project:

import "github.com/gford1000-go/crypto"

Alternatively, you can clone it yourself:

git clone https://github.com/gford1000-go/crypto.git

Testing and benchmarking

To run all tests, cd into the directory and use:

go test -v

Documentation

Overview

Example
package main

import (
	"crypto/sha256"
	"errors"
	"fmt"
)

// MyKeyManager is a simple in-memory key store
type MyKeyManager struct {
	keys map[KeyID]map[[32]byte]Key // The map of keys
}

// saveKey stores the Key as a double map
func (k *MyKeyManager) saveKey(keyID KeyID, key Key, encryptedKey [32]byte) {
	if k.keys == nil {
		k.keys = make(map[KeyID]map[[32]byte]Key)
	}
	_, ok := k.keys[keyID]
	if !ok {
		k.keys[keyID] = make(map[[32]byte]Key)
	}
	k.keys[keyID][encryptedKey] = key
}

// createKeyID can be used to map the context into distinct buckets of keys
func (k *MyKeyManager) createKeyID(context []byte) KeyID {
	return KeyID{} // Here just add to "global" KeyID space
}

// createKey creates a fixed size Key from a random slice of bytes
func (k *MyKeyManager) createKey() Key {
	keyBytes, _ := CreateRandom(KeySize)
	var key Key
	copy(key[:], keyBytes)
	return key
}

// createEncryptedKey can be used to encrypt the supplied key with an envelope key
func (k *MyKeyManager) createEncryptedKey(key Key) [32]byte {
	return sha256.Sum256(key[:]) // Here just hash the key
}

// Create constructs a suitable key based on the context
func (k *MyKeyManager) Create(context []byte) (*KeyDetails, error) {
	keyID := k.createKeyID(context)
	key := k.createKey()
	encKey := k.createEncryptedKey(key)

	k.saveKey(keyID, key, encKey)

	keyDetails := &KeyDetails{
		Key: key,
		EncDetails: EncryptedKeyDetails{
			KeyID:  keyID,
			EncKey: encKey[:],
		},
	}
	return keyDetails, nil
}

// Get uses the specified details to attempt to return the Key
func (k *MyKeyManager) Get(details *EncryptedKeyDetails) (Key, error) {
	if k.keys == nil {
		k.keys = make(map[KeyID]map[[32]byte]Key)
	}
	if m, ok := k.keys[details.KeyID]; ok {
		var encryptedKey [32]byte
		copy(encryptedKey[:], details.EncKey)
		if key, ok := m[encryptedKey]; ok {
			return key, nil
		}
	}
	return InvalidKey, errors.New("Invalid key")
}

func main() {
	// Create a key manager
	manager := &MyKeyManager{}

	// Encrypt some data, with a particular context
	encryptedData, _ := Encrypt([]byte("My Context"), []byte("Hello World"), manager.Create, CreateRandom)

	// Decrypt back to bytes, based only on the encrypted data
	decryptedData, _ := Decrypt(encryptedData, manager.Get)

	fmt.Printf("%s\n", decryptedData)
}
Output:

Hello World

Index

Examples

Constants

View Source
const KeyIDSize = 16

KeyIDSize is the size of the keyID

View Source
const KeySize = 32

KeySize is the size of the key

Variables

View Source
var InvalidKey = Key{}

InvalidKey signifies the key is not populated

Functions

func CreateRandom

func CreateRandom(size int) ([]byte, error)

CreateRandom creates a []byte of the requested number of random values

func Decrypt

func Decrypt(data *EncryptedData, retriever KeyRetriever) ([]byte, error)

Decrypt calls the retriever to obtain a key to decrypt the data. data is expected to have the keyID in its first bytes, of length defined by GetDataKeyIDSize

Types

type EncryptedData

type EncryptedData struct {
	KeyID KeyID  // An identifier associated with the key used to encrypt the data
	Data  []byte // The encrypted data
}

EncryptedData is returned by Encrypt after sucessful encryption

func Encrypt

func Encrypt(context, plaintext []byte, keyCreator KeyCreator, nonceCreator NonceCreator) (*EncryptedData, error)

Encrypt uses keyCreator to retrieve key details and then encrypts the plaintext

context provides metadata associated with the plaintext, and is used to map to a KeyID
plaintext is the data to be encrypted
keyCreator externalises the key generation process
nonceCreator externalises the nonce generation process - note that the nonce must be unique for each call

type EncryptedKeyDetails

type EncryptedKeyDetails struct {
	KeyID  KeyID  // An identifier associated with the key, facilitating decryption
	EncKey []byte // Encrypted key details
}

EncryptedKeyDetails provide the details needed to allow the key to be decrypted

type Key

type Key [KeySize]byte

Key is the type of the encryption key

type KeyCreator

type KeyCreator func([]byte) (*KeyDetails, error)

KeyCreator is a function that returns an instance of KeyDetails, with supplied bytes used to map to the KeyID contained within the KeyDetails

type KeyDetails

type KeyDetails struct {
	EncDetails EncryptedKeyDetails // Details needed to decrypt the key in the future
	Key        Key                 // Plaintext of the key
}

KeyDetails provide the key in plaintext (for immediate encryption activity only), encrypted so this can be prepended to the ciphertext, and with an ID that supports decryption

type KeyID

type KeyID [KeyIDSize]byte

KeyID is an identifier used to identify encryption keys

type KeyRetriever

type KeyRetriever func(*EncryptedKeyDetails) (Key, error)

KeyRetriever is a function that provides a key given an EncryptedKeyDetails instance

type NonceCreator

type NonceCreator func(int) ([]byte, error)

NonceCreator provides nonce values for the AES encryption - these should be unique for each encrypt operation

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL