secret

package
v3.0.0+incompatible Latest Latest
Warning

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

Go to latest
Published: May 15, 2019 License: Apache-2.0 Imports: 11 Imported by: 2

README

Secret

Secret is a library for encrypting and decrypting authenticated messages. 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.

Usage

Demonstrates encryption and decryption of a message using a common key and nonce

import (
	"github.com/mailgun/holster/random"
	"github.com/mailgun/holster/secret"
)
// Create a new randomly generated key
key, err := secret.NewKey()

// Store the key on disk for retrieval later
fd, err := os.Create("/tmp/test-secret.key")
if err != nil {
    panic(err)
}
fd.Write([]byte(secret.KeyToEncodedString(key)))
fd.Close()

// Read base64 encoded key in from disk
s, err := secret.New(&secret.Config{KeyPath: "/tmp/test-secret.key"})
if err != nil {
    panic(err)
}

// Encrypt the message using the key provided and a randomly generated nonce
sealed, err := s.Seal([]byte("hello, world"))
if err != nil {
    panic(err)
}

// Optionally base64 encode them and store them somewhere (like in a database)
cipherText := base64.StdEncoding.EncodeToString(sealed.CiphertextBytes())
nonce := base64.StdEncoding.EncodeToString(sealed.NonceBytes())
fmt.Printf("Ciphertext: %s, Nonce: %s\n", cipherText, nonce)

// Decrypt the message
msg, err := s.Open(&secret.SealedBytes{
    Ciphertext: sealed.CiphertextBytes(),
    Nonce:      sealed.NonceBytes(),
})
fmt.Printf("Decrypted Plaintext: %s\n", string(msg))

// Output: Ciphertext: Pg7RWodWBNwVViVfySz1RTaaVCOo5oJn1E7jWg==, Nonce: AAECAwQFBgcICQoLDA0ODxAREhMUFRYX
// Decrypted Plaintext: hello, world

Convenience Functions

Demonstrates encryption and decryption of a message using a common key and nonce using the package level functions

// Create a or load a new randomly generated key
key, _ := secret.NewKey()

// Encrypt the message using the key provided and a randomly generated nonce
sealed, err := secret.Seal([]byte("hello, world"), key)
if err != nil {
    panic(err)
}

// Optionally base64 encode them and store them somewhere (like in a database)
cipherText := base64.StdEncoding.EncodeToString(sealed.CiphertextBytes())
nonce := base64.StdEncoding.EncodeToString(sealed.NonceBytes())
fmt.Printf("Ciphertext: %s, Nonce: %s\n", cipherText, nonce)

// Decrypt the message
msg, err := secret.Open(&secret.SealedBytes{
    Ciphertext: sealed.CiphertextBytes(),
    Nonce:      sealed.NonceBytes(),
}, key)
fmt.Printf("Decrypted Plaintext: %s\n", string(msg))

// Output: Ciphertext: Pg7RWodWBNwVViVfySz1RTaaVCOo5oJn1E7jWg==, Nonce: AAECAwQFBgcICQoLDA0ODxAREhMUFRYX
// Decrypted Plaintext: hello, world

Key Generation
import (
	"github.com/mailgun/holster/random"
	"github.com/mailgun/holster/secret"
)
// For consistency during tests, DO NOT USE IN PRODUCTION
secret.RandomProvider = &random.FakeRNG{}

// Create a new randomly generated key
keyBytes, _ := secret.NewKey()
fmt.Printf("New Key: %s\n", secret.KeyToEncodedString(keyBytes))

// given key bytes, return an base64 encoded key
encodedKey := secret.KeyToEncodedString(keyBytes)
// given a base64 encoded key, return key bytes
decodedKey, _ := secret.EncodedStringToKey(encodedKey)

fmt.Printf("Key and Encoded/Decoded key are equal: %t", bytes.Equal((*keyBytes)[:], decodedKey[:]))

// Output: New Key: AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8=
// Key and Encoded/Decoded key are equal: true

Testing

Inject a consistent random number generator when writting tests

// For consistency during tests
secret.RandomProvider = &random.FakeRNG{}

// Create a key that will always equal "AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8="
key, _ := secret.NewKey()

Documentation

Overview

Copyright 2017 Mailgun Technologies Inc

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

`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

View Source
var RandomProvider random.RandomProvider

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