streambox

package module
v0.0.0-...-8e0efd8 Latest Latest
Warning

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

Go to latest
Published: Apr 30, 2024 License: Apache-2.0 Imports: 5 Imported by: 0

README

Streambox

Encrypt (and decrypt) an unbounded io.Reader by chunking it into messages and ecrypting them with golang.org/x/crypto/nacl /secretbox.

From golang.org/x/crypto's docs:

Thus large amounts of data should be chunked so that each message is small. (Each message still needs a unique nonce.) If in doubt, 16KB is a reasonable chunk size.

This is exactly what this package provides.

Installation

go get github.com/ozkatz/streambox@latest

Usage

Encrypting an io.Reader
package main

import (
	"io"
	"os"
	
	"github.com/ozkatz/streambox"
)

func main() {
	// this could be any other io.Reader
	fileHandler, err := os.Open("my_big_file.bin")
	if err != nil {
		panic(err)
	}

	// set up an encrypted wrapper around our io.Reader
	// please *never use this secret key*
	secretKey := [32]byte([]byte("12345678912345678912345678912345"))
	r := streambox.Encrypt(secretKey, fileHandler)

	// write it out to a file, or anything else that io.Readers do
	out, err := os.Create("my_big_file.bin.encrypted")
	if err != nil {
		panic(err)
	}
	if _, err := io.Copy(out, r); err != nil {
		panic(err)
	}
	if err := out.Close(); err != nil {
		panic(err)
    }
}

Decrypting an encrypted io.Reader
package main

import (
	"io"
	"os"
	
	"github.com/ozkatz/streambox"
)

func main() {
	// this could be any other io.Reader
	fileHandler, err := os.Open("my_big_file.bin.encrypted")
	if err != nil {
		panic(err)
	}

	// set up an encrypted wrapper around our io.Reader
	// please *never use this secret key*
	secretKey := [32]byte([]byte("12345678912345678912345678912345"))
	r := streambox.Decrypt(secretKey, fileHandler)

	// write it out to a file, or anything else that io.Readers do
	out, err := os.Create("my_big_file.bin")
	if err != nil {
		panic(err)
	}
	if _, err := io.Copy(out, r); err != nil {
		panic(err)
	}
	if err := out.Close(); err != nil {
		panic(err)
	}
}

Implementation

This is a small wrapper around secretbox.Seal and secretbox.Open. Since the module was designed to support small messages, this module wraps an unbounded io.Reader, chunks it into small messages to be Seal()-ed, and emits them as an io.Reader in the following strcuture:

       ┌───
       │<message length (4-byte, BigEndian uint32)>  // includes both nonce and encrypted data
msg #1 │<nonce (24 random bytes)>
       │<encrypted bytes, up to 16Kb>
       └───
       ┌───
       │<message length (4-byte, BigEndian uint32)>  // includes both nonce and encrypted data
msg #2 │<nonce (24 random bytes)>
       │<encrypted bytes, up to 16Kb>
       └───
       ...
       ┌───
       │<message length (4-byte, BigEndian uint32)>  // includes both nonce and encrypted data
msg N  │<nonce (24 random bytes)>
       │<encrypted bytes, up to 16Kb>
       └───

When Decrypting, each message is Open()-ed on the fly, using the nonce and secretKey provided.

This means that this library doesn't do any encryption itself, it simply assembles and decodes chunks of data, of variable sizes. As such, it was also (to the best of my knowledge) not audited by a cryptographer.

Use at your own risk.

License

This library is distributed under the Apache 2.0 license. See LICENSE and NOTICE.

Documentation

Index

Constants

View Source
const (
	// MessageSize is set to 16KB messages, as recommended here:
	// https://pkg.go.dev/golang.org/x/crypto@v0.22.0/nacl/secretbox
	MessageSize = 16 * 1024
)

Variables

View Source
var (
	ErrDecryptingMessage = errors.New("could not decrypt message")
)

Functions

This section is empty.

Types

type DecryptingReader

type DecryptingReader struct {
	SecretKey       [32]byte
	EncryptedStream io.Reader
	// contains filtered or unexported fields
}

func Decrypt

func Decrypt(preSharedKey [32]byte, encryptedStream io.Reader) *DecryptingReader

func (*DecryptingReader) Read

func (r *DecryptingReader) Read(p []byte) (int, error)

type EncryptingReader

type EncryptingReader struct {
	SecretKey         [32]byte
	UnencryptedStream io.Reader
	// contains filtered or unexported fields
}

func Encrypt

func Encrypt(preSharedKey [32]byte, unencryptedStream io.Reader) *EncryptingReader

func (*EncryptingReader) Read

func (r *EncryptingReader) Read(p []byte) (int, error)

Jump to

Keyboard shortcuts

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