goenc

package module
v0.0.0-...-811459a Latest Latest
Warning

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

Go to latest
Published: Mar 12, 2017 License: ISC Imports: 12 Imported by: 1

README

goenc

Go Report Card GoDoc codecov

Encryption and Decryption functions for Go made easy. Encryption should be as simple as calling Encrypt(key, data) and Decrypt(key, data).

###Note: I am in the process of trying to get this reviewed - use at your own risk

API

The API is built around the BlockCipher interface and the Session struct.

BlockCipher can be used to encrypt simple messages or small files.

// BlockCipher represents a cipher that encodes and decodes chunks of data at a time
type BlockCipher interface {
	Encrypt(key, plaintext []byte) ([]byte, error)
   	Decrypt(key, ciphertext []byte) ([]byte, error)
   	KeySize() int
}

Session can be used to perform key exchanges and send secure messages over a "channel" (io.ReadWriter) It also natively performs key derivation, can handle key exchanges, and can prevent replay attaacks. // that is a joke

###Note: Session has been temporarily removed in order to author a more secure version.

// Session represents a session that can be used to pass messages over a secure channel
type Session struct {
   	Cipher   *Cipher
   	Channel
   	lastSent uint32
   	lastRecv uint32
   	sendKey  *[32]byte
   	recvKey  *[32]byte
}

All internal packages implement the BlockCipher interface with a Cipher struct, allowing for flexibility when working with the BlockCipher interface.

Each package can also be used directly, as the Cipher struct in each simply wraps public functions.

This package supports the following types of encryption, all using the Go stdlib with exception for NaCL, which uses Secretbox from the /x/crypto package:


  • AES-CBC

  • AES-CFB

  • AES-CTR

  • AES-GCM

  • NaCL - with a user provided pad

  • ####All types support encryption + authentication


#####Example Usage of package functions

key := []byte("some 32 byte key") // obviously this would fail without being 32 bytes
ciphertext, err := gcm.Encrypt(key, []byte("super secret message"))
if err != nil {
    return err
}
plaintext, err := gcm.Decrypt(key, ciphertext)
if err != nil {
    return err  
}
fmt.Println(plaintext) // super secret message

#####Example Usage of the main Cipher struct and a BlockCipher interface - this will perform key derivation

c, err := goenc.NewCipher(goenc.CBC, goenc.InteractiveComplexity)
if err != nil {
    return err
}
ciphertext, err := c.Encrypt(key, []byte("super secret message"))
if err != nil {
    return err       
}
plaintext, err := c.Decrypt(key, ciphertext)
if err != nil {
    return err
}    
fmt.Println(plaintext) // super secret message

#####Example Usages of Session

Note: Retries and connection breaking are not shown here

######As a server

// wait until a client connects and performs a key exchange
s, err := goenc.Listen(readWriter, cipher)
// if exchange is bad or none was given, we return
if err != nil {
    return err
}

// s is now a session on the given readWriter (underlying conn) and can wait to receive messages
for {
    msg, err := s.Receive()
    is err != nil {
        // check for closed connection here and break if it is (not shown)
        someErrChan <- err
        continue
    }
    
    msg, err := someMsgParsingFunc(msg)
    if err != nil {
        // garbled message
        someErrChan <- err
        continue
    }
    
    switch msg.Type {
        case SomeCoolThing:
            err = s.Send(someConstMessage)
            if err != nil {
                someErrChan <- err
            }
        default:
            // successfully parsed but we don't know what to do, probably retry parsing
    }
}

######As a client

// initial connection to underlying conn of readWriter
s, err := goenc.Dial(readWriter, cipher)
if err != nil {
    return err
}

// send an initial message
err := s.Send(someMessage)
        is err != nil {
            return err
        }
for {
       
        // wait for response
        msg, err := s.Receive()
        if err != nil {
            someErrChan <- err
            continue
        }
        
        msg, err = someMsgParsingFunc(msg)
        if err != nil {
            // garbled message
            someErrChan <- err
            continue
        }
        
        switch msg.Type {
            case SomeCoolThing:
                err = s.Send(someConstMessage)
                if err != nil {
                    someErrChan <- err
                }
            default:
                // successfully parsed but we don't know what to do, probably retry parsing
        }
    }

#SSH Package

The ssh package contains convenience functions for generating and parsing ssh keys. They are a wrapper around the /x/crypto package's ssh package.

TODO

1. [ ] Get project reviewed (if you are a security expert interested in reviewing this, please contact me and let me know if you find anything)
2. [ ] More complete documentation with examples
    *  [ ] Document full examples of package functions and the small differences they have
    *  [ ] Document SenderID functions in the GCM package and give a real world example
3. [ ] Implement SenderID functions in packages other than GCM
4. [ ] Give user level control over when/how key derivation takes place
    *  The way it works now on a session is that the key will be derived for every message - this is slow, but potentially more secure
       * If one algo has a flaw in which a prior key is discovered, only that message could be read
       * That should still be left up to the user
    *  [ ] Allow user given salt   

#Special Thanks

A very special thanks to Kyle Isom, whose book provided a very good jumping off point for starting this library.

You can find his book here: Practical Cryptography with Go

Documentation

Overview

Package goenc contains functions for working with encryption

Index

Constants

View Source
const (

	// InteractiveComplexity - recommended complexity for interactive sessions
	InteractiveComplexity = 1 << (iota + 14)
	// Complexity15 is 2^15
	Complexity15
	// Complexity16 is 2^16
	Complexity16
	// Complexity17 is 2^17
	Complexity17
	// Complexity18 is 2^18
	Complexity18
	// Complexity19 is 2^19
	Complexity19
	// AggressiveComplexity is 2^20 (don't use this unless you have incredibly strong CPU power
	AggressiveComplexity
)

Overhead is the amount of Overhead contained in the ciphertext

View Source
const (
	// SaltSize sets a generic salt size
	SaltSize = 64
)

Variables

This section is empty.

Functions

func DeriveKey

func DeriveKey(pass, salt []byte, N, keySize int) ([]byte, error)

DeriveKey generates a new NaCl key from a passphrase and salt. This is a costly operation.

func EncryptAndSave

func EncryptAndSave(cipher BlockCipher, key, plaintext []byte, path string) error

EncryptAndSave encrypts data and saves it to a file with the permissions 0644

func EncryptAndSaveWithPerms

func EncryptAndSaveWithPerms(cipher BlockCipher, key, plaintext []byte, path string, perm os.FileMode) error

EncryptAndSaveWithPerms encrypts data and saves it to a file with the given permissions using the given key

func ReadEncryptedFile

func ReadEncryptedFile(cipher BlockCipher, key []byte, path string) ([]byte, error)

ReadEncryptedFile reads a file a path and attempts to decrypt the data there with the given key

func Zero

func Zero(data []byte)

Zero zeroes out bytes of data so that it does not stay in memory any longer than necessary

Types

type BlockCipher

type BlockCipher interface {
	Encrypt(key, plaintext []byte) ([]byte, error)
	Decrypt(key, ciphertext []byte) ([]byte, error)
	KeySize() int
}

BlockCipher represents a cipher that encodes and decodes chunks of data at a time

type Cipher

type Cipher struct {
	BlockCipher
	DerivedKeyN int
}

Cipher is a struct that contains a BlockCipher interface and stores a DerivedKey Complexity number

func NewCipher

func NewCipher(kind CipherKind, derivedKeyN int, args ...[]byte) (*Cipher, error)

NewCipher returns a new Cipher containing a BlockCipher interface based on the CipherKind

func (*Cipher) DecryptWithPassword

func (c *Cipher) DecryptWithPassword(password, ciphertext []byte) ([]byte, error)

Decrypt takes a password and ciphertext, derives a key, and attempts to decrypt that data

func (*Cipher) DeriveKey

func (c *Cipher) DeriveKey(pass, salt []byte) ([]byte, error)

func (*Cipher) EncryptWithPassword

func (c *Cipher) EncryptWithPassword(password, plaintext []byte) ([]byte, error)

EncryptWithPassword takes a password, plaintext, and derives a key based on that password, then encrypting that data with the underlying block cipher and appending the salt to the output

type CipherKind

type CipherKind int

CipherKind represents what kind of cipher to use

const (
	CBC CipherKind = iota
	CFB
	CTR
	GCM
	NaCL

	Mock
)

CipherKind constants

type Message

type Message struct {
	Number   uint32
	Contents []byte
}

Message represents a message being passed, and contains its contents and a sequence number

func NewMessage

func NewMessage(in []byte, num uint32) *Message

NewMessage returns a new message

func UnmarshalMessage

func UnmarshalMessage(in []byte) (*Message, error)

UnmarshalMessage decodes bytes into a message pointer

func (*Message) Marshal

func (m *Message) Marshal() []byte

Marshal encodes a sequence number into the data that we wish to send

type MockBlockCipher

type MockBlockCipher struct{}

MockBlockCipher implements BlockCipher but does nothing

func (*MockBlockCipher) Decrypt

func (m *MockBlockCipher) Decrypt(key, ciphertext []byte) ([]byte, error)

Decrypt in this case is only implementing the BlockCipher interface, it doesn't do anything

func (*MockBlockCipher) Encrypt

func (m *MockBlockCipher) Encrypt(key, plaintext []byte) ([]byte, error)

Encrypt in this case is only implementing the BlockCipher interface, it doesn't do anything

func (*MockBlockCipher) KeySize

func (m *MockBlockCipher) KeySize() int

KeySize is a mock key size to use with the mock cipher

Directories

Path Synopsis
aes
cbc
Package cbc supports cbc encryption - this implementation is authenticated with crypto/hmac using sha256
Package cbc supports cbc encryption - this implementation is authenticated with crypto/hmac using sha256
cfb
Package cfb supports basic cfb encryption with NO HMAC
Package cfb supports basic cfb encryption with NO HMAC
ctr
Package ctr supports ctr encryption - this implementation is authenticated with crypto/hmac using sha256
Package ctr supports ctr encryption - this implementation is authenticated with crypto/hmac using sha256
gcm
Package gcm supports gcm encryption - gcm is authenticated by default
Package gcm supports gcm encryption - gcm is authenticated by default
Package nacl provides encryption by salting a key with a pad
Package nacl provides encryption by salting a key with a pad
Package ssh supports generation of key pairs in different formats with as few parameters as possible
Package ssh supports generation of key pairs in different formats with as few parameters as possible

Jump to

Keyboard shortcuts

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