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 ¶
const KeyIDSize = 16
KeyIDSize is the size of the keyID
const KeySize = 32
KeySize is the size of the key
Variables ¶
var InvalidKey = Key{}
InvalidKey signifies the key is not populated
Functions ¶
func CreateRandom ¶
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 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 KeyRetriever ¶
type KeyRetriever func(*EncryptedKeyDetails) (Key, error)
KeyRetriever is a function that provides a key given an EncryptedKeyDetails instance
type NonceCreator ¶
NonceCreator provides nonce values for the AES encryption - these should be unique for each encrypt operation