encrypt

package module
v0.0.2 Latest Latest
Warning

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

Go to latest
Published: Mar 19, 2022 License: MIT Imports: 8 Imported by: 0

README

GoDoc Go Go Report Card Coverage

Keywords: Go (golang) AES file encryption reader/writer.

Overview

Package encrypt provides io.Writer, io.Reader, and io.ReadSeeker implementations useful for file encryption.

How It Works

This implementation chunks the input into individually-encrypted segments of approximately 64KB in length, which allows reading and writing to operate on large files or streams without loading the entire file into memory at once.

Each chunk is concatenated with a random 96-bit nonce and 128-bit Message Authentication Code (MAC) to prevent tampering. As a result the size on disk will be 28*N bytes larger than the input, where N is the number of segments the file was broken into. For a 10GB file this translates to approximately 4.3MB of overhead.

Encryption uses AES-GCM with 256-bit keys.

The individual chunks are encrypted following the examples from https://github.com/gtank/cryptopasta (see the Crypto for Go Developers talk for details).

Relevant Talks:

Crypto for Go Developers: https://www.youtube.com/watch?v=2r_KMzXB74w

End-to-End File Encryption (In Web Browsers): https://www.youtube.com/watch?v=SdePc87Ffik

Disclaimer

This implementation has not been validated by encryption experts, nor has it been optimized for performance. Use at your own risk.

Documentation

Overview

Package encrypt provides io.Writer and io.Reader implementations useful for symmetric file encryption.

How It Works

This implementation chunks the input into individually-encrypted segments of approximately 64KB in length, which allows reading and writing to operate on large files or streams without loading the entire file into memory at once.

Each chunk is concatenated with an IV and Message Authentication Code, which results in encrypted files that are larger than the source data. For a 10GB file this results in approximately 4.3MB of additional data.

Encryption uses AES-GCM with 256-bit keys.

Index

Examples

Constants

This section is empty.

Variables

View Source
var ErrInvalidKeyLength = errors.New("expected 32-byte key")

ErrInvalidKeyLength is returned by DecodeBase64Key when a key of the wrong size is decoded.

Functions

This section is empty.

Types

type Key

type Key [32]byte

Key is a 256-bit key used for AES-GCM encryption and decryption.

func DecodeBase64Key

func DecodeBase64Key(s string) (key Key, err error)

DecodeBase64Key decodes a base64-encoded key.

func NewKey

func NewKey() (key Key, err error)

NewKey generates a new random key for symmetric encryption. A non-nil error is cause for panic.

Example
package main

import (
	"bytes"

	"github.com/Travis-Britz/encrypt"
)

func main() {
	// generate a new key
	key, err := encrypt.NewKey()
	if err != nil {
		panic(err)
	}

	// save the key somewhere safe
	// use key.String() for serialization

	// encrypt data using the key
	encrypter := encrypt.NewWriter(&bytes.Buffer{}, key)
	_, _ = encrypter.Write([]byte("plaintext"))
	_ = encrypter.Close()
}
Output:

func (Key) String

func (key Key) String() string

String converts key to a string using standard base64 encoding, which is generally more portable between programs than 32 bytes of random binary data.

type Reader

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

Reader is an io.Reader capable of decrypting data that was encrypted by Writer.

func NewReader

func NewReader(r io.Reader, key Key) *Reader

NewReader returns a new Reader for decrypting r, where r was encrypted by a Writer using key.

func (*Reader) Read

func (r *Reader) Read(p []byte) (n int, err error)

Read implements io.Reader.

func (*Reader) Seek

func (r *Reader) Seek(offset int64, whence int) (int64, error)

Seek sets the offset for the next Read, partially implementing io.Seeker: io.SeekStart means relative to the start of the file, io.SeekCurrent means relative to the current offset. io.SeekEnd is only supported for specific types.

Seek will return an error if r.r is not an io.Seeker.

type Writer

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

Writer is an io.Writer for encrypting data.

func NewWriter

func NewWriter(w io.Writer, key Key) *Writer

NewWriter returns a new Writer that encrypts data with key before writing to w. Callers must call Close to write the final chunk of data.

Example
package main

import (
	"bytes"
	"fmt"

	"github.com/Travis-Britz/encrypt"
)

func main() {
	plaintext := []byte("Hello, world!")
	key, _ := encrypt.DecodeBase64Key("VGVzdEtleTAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDA=")
	buf := &bytes.Buffer{}

	encrypter := encrypt.NewWriter(buf, key)
	_, _ = encrypter.Write(plaintext)

	// This example reads back the data from the file inside the same function,
	// so we call Close now instead of deferring to force pending data to flush.
	_ = encrypter.Close()

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

	// Each chunk of ciphertext begins with a 96-bit (12-byte) random nonce
	// and ends with a 128-bit (16-byte) Message Authentication Code (MAC).
	fmt.Printf("ciphertext: %v\n", buf.Bytes())
}
Output:

func (*Writer) Close

func (w *Writer) Close() error

Close flushes any remaining data from the buffer to the underlying writer and prevents additional calls to Write.

func (*Writer) Write

func (w *Writer) Write(p []byte) (n int, err error)

Write writes p to an internal buffer to ensure that encrypted chunks have uniform size. The buffer is encrypted and flushed as needed.

Callers must call w.Close to flush the final chunk from the buffer.

Jump to

Keyboard shortcuts

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