secret

package
v0.0.0-...-4214099 Latest Latest
Warning

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

Go to latest
Published: Jun 19, 2017 License: Apache-2.0 Imports: 11 Imported by: 42

README

secret

Mailgun tools for authenticated encryption.

Overview

Package secret provides tools for encrypting and decrypting authenticated messages. Like all lemma packages, metrics are built in and can be emitted to check for anomalous behavior.

NaCl is the underlying secret-key authenticated encryption library used. NaCl uses Salsa20 and Poly1305 as its cipher and MAC respectively.

Examples

Key generation and use

package main

import (
    "github.com/mailgun/lemma/secret"
)

// generate a new randomly generated key. use this to create a new key.
keyBytes, err := secret.NewKey()

// read base64 encoded key in from disk
secretService, err := secret.New(&secret.Config{KeyPath: "/path/to/secret.key"})

// set key bytes directly
secretService, err := secret.New(&secret.Config{
    KeyBytes: &[32]byte{
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    },
})

// given a base64 encoded key, return key bytes
secret.EncodedStringToKey("c3VycHJpc2UsIHRoaXMgaXMgYSBmYWtlIGtleSE=")

// given key bytes, return an base64 encoded key
secret.KeyToEncodedString(&[32]byte{
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
})

Encrypt message with existing key

import (
    "fmt"
    "encoding/base64"

    "github.com/mailgun/lemma/secret"
)

// create a new secret encryption service using the above generated key
s, err := secret.New(&secret.Config{KeyPath: "/path/to/secret.key"})
if err != nil {
    fmt.Printf("Got unexpected response from NewWithKeyBytes: %v\n", err)
}

// seal message
message := []byte("hello, world")
sealed, err := s.Seal(message)
if err != nil {
    fmt.Printf("Got unexpected response from Seal: %v\n", err)
}

// optionally base64 encode them and store them somewhere (like in a database)
ciphertext := base64.StdEncoding.EncodeToString(sealed.Ciphertext)
nonce := base64.StdEncoding.EncodeToString(sealed.Nonce)
fmt.Printf("Ciphertext: %v, Nonce: %v\n", ciphertext, nonce)

Encrypt message with passed in key

import (
    "fmt"
    "github.com/mailgun/lemma/secret"
)

// create a new secret encryption service using the above generated key
s, err := secret.New(&secret.Config{KeyPath: "/path/to/secret.key"})
if err != nil {
    fmt.Printf("Got unexpected response from NewWithKeyBytes: %v\n", err)
}

// seal message
message := []byte("hello, world")
messageKey := secret.KeyBytes: &[32]byte{
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
}
sealed, err := s.SealWithKey(message, messageKey)
if err != nil {
    fmt.Printf("Got unexpected response from Seal: %v\n", err)
}

fmt.Printf("Ciphertext: %v, Nonce: %v\n", sealed.Ciphertext, sealed.Nonce)

Decrypt message

import (
    "fmt"
    "github.com/mailgun/lemma/secret"
)

// create a new secret encryption service using the above generated key
s, err := secret.New(&secret.Config{KeyPath: "/path/to/secret.key"})
if err != nil {
    fmt.Printf("Got unexpected response from NewWithKeyBytes: %v\n", err)
}

var ciphertext []byte
var nonce []byte

// read in ciphertext and nonce
[...]

// decrypt and open message
plaintext, err := s.Open(&secret.SealedBytes{
    Ciphertext: ciphertext,
    Nonce:      nonce,
})
if err != nil {
    fmt.Printf("Got unexpected response from Open: %v\n", err)
}

fmt.Printf("Plaintext: %v\n", plaintext)

Emit Metrics

import (
    "fmt"
    "github.com/mailgun/lemma/secret"
)

// define statsd server for metrics
s, err := secret.New(&secret.Config{
    KeyPath:      "/path/to/secret.key",

    EmitStats:    true,
    StatsdHost:   "www.example.com",
    StatsdPort:   8125,
    StatsdPrefix: "a_secret_prefix",
})

// now, when using the service, success and failures will be emitted to statsd
plaintext, err := s.Open(...)
if err != nil {
    fmt.Printf("Got unexpected response from Open: %v\n", err)
}

Documentation

Overview

Package secret provides tools for encrypting and decrypting authenticated messages. See docs/secret.md for more details.

Index

Constants

View Source
const NonceLength = 24 // length of nonce
View Source
const SecretKeyLength = 32 // lenght of secret key

Variables

This section is empty.

Functions

func EncodedStringToKey

func EncodedStringToKey(encodedKey string) (*[SecretKeyLength]byte, error)

EncodedStringToKey converts a base64-encoded string into key bytes.

func KeySliceToArray

func KeySliceToArray(bytes []byte) (*[SecretKeyLength]byte, error)

func KeyToEncodedString

func KeyToEncodedString(keybytes *[SecretKeyLength]byte) string

KeyToEncodedString converts bytes into a base64-encoded string

func NewKey

func NewKey() (*[SecretKeyLength]byte, error)

NewKey returns a new key that can be used to encrypt and decrypt messages.

func Open

func Open(e SealedData, secretKey *[SecretKeyLength]byte) ([]byte, error)

Open authenticates the ciphertext and if valid, decrypts and returns plaintext. Allows passing in a key and useful for one off opening purposes, otherwise create a secret.Service to open multiple times.

func ReadKeyFromDisk

func ReadKeyFromDisk(keypath string) (*[SecretKeyLength]byte, error)

func SealedDataToString

func SealedDataToString(sealedData SealedData) (string, error)

Given SealedData returns equivalent URL safe base64 encoded string.

Types

type Config

type Config struct {
	KeyPath  string
	KeyBytes *[SecretKeyLength]byte

	EmitStats    bool   // toggle emitting metrics or not
	StatsdHost   string // hostname of statsd server
	StatsdPort   int    // port of statsd server
	StatsdPrefix string // prefix to prepend to metrics
}

Config is used to configure a secret service. It contains either the key path or key bytes to use.

type SealedBytes

type SealedBytes struct {
	Ciphertext []byte
	Nonce      []byte
}

SealedBytes contains the ciphertext and nonce for a sealed message.

func (*SealedBytes) CiphertextBytes

func (s *SealedBytes) CiphertextBytes() []byte

func (*SealedBytes) CiphertextHex

func (s *SealedBytes) CiphertextHex() string

func (*SealedBytes) NonceBytes

func (s *SealedBytes) NonceBytes() []byte

func (*SealedBytes) NonceHex

func (s *SealedBytes) NonceHex() string

type SealedData

type SealedData interface {
	CiphertextBytes() []byte
	CiphertextHex() string

	NonceBytes() []byte
	NonceHex() string
}

SealedData respresents an encrypted and authenticated message.

func Seal

func Seal(value []byte, secretKey *[SecretKeyLength]byte) (SealedData, error)

Seal takes plaintext and a key and returns encrypted and authenticated ciphertext. Allows passing in a key and useful for one off sealing purposes, otherwise create a secret.Service to seal multiple times.

func StringToSealedData

func StringToSealedData(encodedBytes string) (SealedData, error)

Given a URL safe base64 encoded string, returns SealedData.

type SecretService

type SecretService interface {
	// Seal takes a plaintext message and returns an encrypted and authenticated ciphertext.
	Seal([]byte) (SealedData, error)

	// Open authenticates the ciphertext and, if it is valid, decrypts and returns plaintext.
	Open(SealedData) ([]byte, error)
}

SecretSevice is an interface for encrypting/decrypting and authenticating messages.

func New

func New(config *Config) (SecretService, error)

New returns a new Service. Config can not be nil.

type Service

type Service struct {
	// contains filtered or unexported fields
}

A Service can be used to seal/open (encrypt/decrypt and authenticate) messages.

func (*Service) Open

func (s *Service) Open(e SealedData) (byt []byte, err error)

Open authenticates the ciphertext and if valid, decrypts and returns plaintext.

func (*Service) Seal

func (s *Service) Seal(value []byte) (SealedData, error)

Seal takes plaintext and returns encrypted and authenticated ciphertext.

Jump to

Keyboard shortcuts

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