superdog

package module
v1.0.0 Latest Latest
Warning

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

Go to latest
Published: Dec 7, 2015 License: MIT Imports: 12 Imported by: 2

README

Superdog - the Crypto library for Vault from Hashicorp

GoDoc

Superdog is a library for managing strong cryptography in both development and test environments. Superdog provides an elegant wrapper to the Vault API that allows you to manage your cryptographic keys using any code that implements the KeyProvider interface. An implemention of the KeyProvider interface is provided for Vault, but others could be supported.

Intro article

Features

  • Versioned Keys - Key version is stored as the first few bytes of the encrypted text
  • Key Rotation - Rotate your keys safely, knowing that you'll always be able to decrypt older versionss
  • Development implementation for tests and local development
  • Versioned and Rotated IV/Salt - SaltProvider interface works the same as KeyProvider to allow development and testing access to the crypto libraries without requiring a live Key (Vault) server
  • Reencrypt function to simplify key rotation, decrypts with given key, reencrypts with latest key

Cypher Suites

superdog supports AES encryption with CFB/CTR/GCM/OFB modes.

Performance

On Go version 1.5.2 / Linux x86_64 kernel 4.2.5 on a quad-core i7:

BenchmarkKeyEncryptCFB-8	 1000000	      2024 ns/op
BenchmarkKeyEncryptCTR-8	  500000	      2748 ns/op
BenchmarkKeyEncryptGCM-8	 1000000	      2381 ns/op
BenchmarkKeyEncryptOFB-8	  500000	      2665 ns/op
BenchmarkKeyDecryptCFB-8	10000000	       215 ns/op
BenchmarkKeyDecryptCTR-8	 2000000	       898 ns/op
BenchmarkKeyDecryptGCM-8	 3000000	       520 ns/op
BenchmarkKeyDecryptOFB-8	 2000000	       817 ns/op

Usage

go get -u github.com/xordataexchange/superdog/...

Encryption
val := []byte("encrypt me!")

// use a key prefix to delineate different crypto keys
// allowing you to use different keys for different parts of your application
// or different fields of a database table, for example
b, err := Encrypt("mykeyprefix", val, val)
if err != nil {
	// handle error
}
Decryption
	b := []byte["some crypt cypher text here"]
	decrypted, err := Decrypt([]byte("mykeyprefix", b, b)
	if err != nil {
		// handle error
	}

Production Usage

By default, superdog uses the DevKeyProvider which is a static key with static IV. This is extremely insecure, and SHOULD NOT ever be used in production.

We reccommend using Go's build tags to enable strong cryptography in production usage.

Create a file with your connection routines in the init() function. Add the build tag // +build production to the top of that file. Here's an incomplete example:

// +build production

package main
import (
	"github.com/xordataexchange/superdog"
	"github.com/xordataexxchange/superdog/vault/hashi"
	"github.com/hashicorp/vault/api"
)

// Assign each application a unique UUID
// and use Vault's AppID authentication mechanism
const (
	appid = "SOME RANDOM UUID"
)

func init() {
	user := os.Getenv("VAULT_USER")
	vaultaddr := os.Getenv("VAULT_ADDRESS")
	// TEST these for empty strings & handle appropriately in your code

	cfg:= api.DefaultConfig()
	cfg.Address = vaultaddr

	vault, err := hashi.NewVault(cfg)
	if err != nil {
		// handle appropriately
	}
	err = vault.AuthAppID(appid, user)
	if err != nil {
		// handle appropriately
	}

	crypto.DefaultKeyProvider = vault
	crypto.DefaultSaltProvider = vault

}

Now compile your program with go build -tags production to include this code. The KeyProvider will be set to use Vault.

Documentation

Overview

See LICENSE file for license details Copyright (c) 2015 XOR Data Exchange, Inc.

Superdog - the Crypto library for Vault from Hashicorp

Superdog is a library for managing strong cryptography in both development and test environments. Superdog provides an elegant wrapper to the Vault(https://www.vaultproject.io) API that allows you to manage your cryptographic keys in Vault using any code that implements the `KeyProvider` interface. An implemention of the `KeyProvider` interface is provided for Vault, but others could be supported.

Features

- Versioned Keys - Key version is stored as the first few bytes of the encrypted text - Key Rotation - Rotate your keys safely, knowing that you'll always be able to decrypt older versionss - Development implementation for tests and local development - Versioned and Rotated IV/Salt - `SaltProvider` interface works the same as `KeyProvider` to allow development and testing access to the crypto libraries without requiring a live Key (Vault) server - `Reencrypt` function to simplify key rotation, decrypts with given key, reencrypts with latest key

Cypher Suites

`superdog` supports AES encryption with CFB/CTR/GCM/OFB modes.

Production Usage By default, `superdog` uses the `DevKeyProvider` which is a static key with static IV. This is extremely insecure, and SHOULD NOT ever be used in production.

We reccommend using Go's [build tags](https://golang.org/pkg/go/build/) to enable strong cryptography in production usage.

Create a file with your connection routines in the init() function. Add the build tag `// +build production` to the top of that file. Incomplete example:

// +build production

package main
import (
	"github.com/xordataexchange/superdog"
	"github.com/xordataexxchange/superdog/vault/hashi"
	"github.com/hashicorp/vault/api"
)

// Assign each application a unique UUID
// and use Vault's AppID authentication mechanism
const (
	appid = "SOME RANDOM UUID"
)

func init() {
	user := os.Getenv("VAULT_USER")
	vaultaddr := os.Getenv("VAULT_ADDRESS")
	// TEST these for empty strings & handle appropriately in your code
	cfg:= api.DefaultConfig()
	cfg.Address = vaultaddr
	vault, err := hashi.NewVault(cfg)
	if err != nil {
		// handle appropriately
	}
	err = vault.AuthAppID(appid, user)
	if err != nil {
		// handle appropriately
	}
	crypto.DefaultKeyProvider = vault
	crypto.DefaultSaltProvider = vault
}

Now compile your program with `go build -tags production` to include this code. The `KeyProvider` will be set to use Vault.

Index

Constants

This section is empty.

Variables

View Source
var (
	ErrKeyNotFound = errors.New("Key not found")
)

Functions

func CurrentHashes

func CurrentHashes(prefix string, value []byte) ([][]byte, error)

CurrentHashes returns a list of all possible hashes for the given prefix and value, used as search criteria during rotation

func CurrentHashesString

func CurrentHashesString(prefix string, value string) ([]string, error)

CurrentHashesString returns a list of all possible hashes for the given prefix and value, used as search criteria during rotation

func Decrypt

func Decrypt(keyPrefix string, dst, src []byte) ([]byte, error)

Decrypt will decrypt the provided byte slice using the provided key at the version it was encrypted with. It returns a new slice as it trims the prefixed key version and IV. It modifies the same underlying array.

func Encrypt

func Encrypt(prefix string, dst, src []byte) ([]byte, error)

Encrypt will encrypt the provided byte slice with the latesg key. It returns a new slice as it prepends the key version, and IV.

func EncryptWithVersion

func EncryptWithVersion(keyPrefix string, keyVersion uint64, dst []byte, src []byte) ([]byte, error)

EncryptWithVersion will encrypt the provided byte slice with the supplied key version. It returns a new slice as it prepends the key version, and IV.

func Hash

func Hash(prefix string, value []byte) ([]byte, error)

Hash returns a hash to be used for the given value using the current version

func HashString

func HashString(prefix string, value string) (string, error)

HashString returns a hash to be used for the given value using the current version

func HashWithVersion

func HashWithVersion(prefix string, version uint64, value []byte) ([]byte, error)

HashWithVersion returns a hash to be used for the given value using the supplied version

func Reencrypt

func Reencrypt(keyPrefix string, dst, src []byte) ([]byte, error)

Reencrypt takes encrypted ciphertext, decrypts it with the version of the key used to decrypt it, and re-encrypts the plaintext with the current version of the key.

func Sum256String

func Sum256String(s string) string

Types

type Cipher

type Cipher uint8
const (
	AES Cipher = iota
)

type CipherBlockMode

type CipherBlockMode uint8
const (
	CFB CipherBlockMode = iota
	CTR
	OFB
	GCM
)

type DevKeyProvider

type DevKeyProvider struct {
	DisableWarn bool // Disable log messages whenever this provider is used.
	KeyVersion  uint64
}

DevKeyProvider is a KeyProvider used for development purposes only, and contains a hardcoded key.

func (*DevKeyProvider) CurrentKeyVersion

func (kp *DevKeyProvider) CurrentKeyVersion(prefix string) (uint64, error)

CurrentKeyVersion returns the version number of the latest key for a given prefix

func (*DevKeyProvider) GetKey

func (kp *DevKeyProvider) GetKey(prefix string, version uint64) (*Key, error)

type DevSaltProvider

type DevSaltProvider struct {
	DisableWarn bool // Disable log messages whenever this provider is used.
	SaltVersion uint64
}

DevSaltProvider is a KeyProvider used for development purposes only, and contains a hardcoded key.

func (*DevSaltProvider) CurrentSaltVersion

func (sp *DevSaltProvider) CurrentSaltVersion(prefix string) (uint64, error)

CurrentSaltVersion returns the version number of the latest salt for a given prefix

func (*DevSaltProvider) CurrentSalts

func (sp *DevSaltProvider) CurrentSalts(prefix string) ([]uint64, error)

CurrentSalts returns a stubbed list of salts to be used for the given prefix

func (*DevSaltProvider) GetSalt

func (sp *DevSaltProvider) GetSalt(prefix string, version uint64) ([]byte, error)

GetSalt returns a stubbed salt to be used for the given prefix

type Key

type Key struct {
	Cipher          Cipher
	CipherBlockMode CipherBlockMode

	Version uint64
	// contains filtered or unexported fields
}

func NewKey

func NewKey(version uint64, c Cipher, bm CipherBlockMode, key []byte) (*Key, error)

func (*Key) Decrypt

func (k *Key) Decrypt(dst, src []byte) ([]byte, error)

func (*Key) Encrypt

func (k *Key) Encrypt(dst, src []byte) ([]byte, error)

type KeyProvider

type KeyProvider interface {
	GetKey(prefix string, version uint64) (*Key, error)
	CurrentKeyVersion(prefix string) (uint64, error)
}

KeyProvider is an interface that wraps the GetKey method, responsible for retrieving encryption keys at a specified version.

var DefaultKeyProvider KeyProvider = new(DevKeyProvider)

type SaltProvider

type SaltProvider interface {
	CurrentSalts(prefix string) ([]uint64, error)
	GetSalt(prefix string, version uint64) ([]byte, error)
	CurrentSaltVersion(prefix string) (uint64, error)
}
var DefaultSaltProvider SaltProvider = new(DevSaltProvider)

Directories

Path Synopsis
See LICENSE file for license details Copyright (c) 2015 XOR Data Exchange, Inc.
See LICENSE file for license details Copyright (c) 2015 XOR Data Exchange, Inc.
hashi
See LICENSE file for license details Copyright (c) 2015 XOR Data Exchange, Inc.
See LICENSE file for license details Copyright (c) 2015 XOR Data Exchange, Inc.

Jump to

Keyboard shortcuts

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