+
Skip to content

Provides io.Writer and io.Reader that transparently compresses and encrypts a stream of data using the modern best practices: zstd and ChaCha20-Poly1305 AEAD with an ephemeral key.

License

Notifications You must be signed in to change notification settings

andreyvit/sealer

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

6 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

sealer

Go reference under 350 LOC Go Report Card

Provides io.Writer and io.Reader that transparently compresses and encrypts a stream of data using the modern best practices: zstd and ChaCha20-Poly1305 AEAD with an ephemeral key.

Has only two dependencies:

Sealer is a bit like filippo.io/age, but simpler and meant for custom encrypted file formats.

  • supports a custom unencrypted file header that comes before the data (the header is authenticated as part of the first encrypted block, so tampering and corruption will be detected);

  • single secret encryption key only (with a 32-byte user-definable KeyID so that you can look up the key in your system's keystore).

Usage

Install:

go get github.com/andreyvit/sealer@latest

and then:

import (
	"github.com/andreyvit/sealer"
)

Generating a key

A key is just a [32]byte user-defined identifier and a [32]byte secret key material:

key := &sealer.Key{}
copy(key.ID[:], "YA_CAN_PUT_WHATEVER_YA_WANT_HERE")

_, err := io.ReadFull(cryptoRand.Reader, key.Key[:])
if err != nil {
	panic(err)
}

32 bytes of Key ID is enough to hold an integer (or four), a UUID (or two), a string name, or SHA-256 hash of any data — the usage is up to you.

Sealing (aka encrypting)

Example:

// prefix is any []byte you want to prepend to the file, can be nil.
w, err := sealer.Seal(outputWriter, key, prefix, sealer.SealOptions{})
if err != nil {
	panic(err)
}

for range 100 {
	_, err := w.Write(data)
	if err != nil {
		panic(err)
	}
}

// Very important to close the writer to write out the final chunk.
err = w.Close()
if err != nil {
	panic(err)
}

If you provide a prefix, sealer.Seal will write it to the beginning of the file.

Opening (aka decrypting)

Example:

o, err := sealer.Prepare(inputReader, prefix)
if err != nil {
	panic(err)
}

key := lookupKey(o.KeyID)

r, err := o.Open(key)
if err != nil {
	panic(err)
}

// Read from r now, for example:
var opened bytes.Buffer
_, err = io.Copy(&opened, r)
if err != nil {
	panic(err)
}

Unlike sealer, opener will not read the prefix for you — it assumes you've already read the file header to make sense of what it is. So if you want a prefix, read it yourself before calling sealer.Prepare:

prefix := make([]byte, prefixLen)
_, err := io.ReadFull(inputReader, prefix)
if err != nil {
	panic(err)
}

Encryption & Compression

Uses modern best practices for cryptography:

  • ChaCha20-Poly1305 encryption;

  • ephemeral (i.e. per-file) encryption key that is encapsulated by the encryption key;

  • encapsulation uses XChaCha20-Poly1305 with a random 192-bit nonce;

  • encryption splits the file into chunks (32 KB by default) and uses deterministic nonces for these, marking the final chunk's nonce to detect trimming;

  • nothing of the above is configurable.

ChaCha20-Poly1305 has been chosen as a modern and standardized cipher, ensuring wide availability and interoperability. NaCl's XSalsa20-Poly1305 would be similar, but it's not a standard so ChaCha20 seems like a better choice going forward. AES-256-GCM could also be used here, but ChaCha20 has fewer concerns about complicated attack scenarios.

Before encryption, sealer applies zstd compression, it provides an excellent time/compression balance and has an accepted proposal for inclusion in Go stdlib. Until that happens, we use github.com/klauspost/compress/zstd which is an excellent zero-dependency library.

License

Copyright 2025, Andrey Tarantsov. Distributed under the 2-clause BSD license.

About

Provides io.Writer and io.Reader that transparently compresses and encrypts a stream of data using the modern best practices: zstd and ChaCha20-Poly1305 AEAD with an ephemeral key.

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages

点击 这是indexloc提供的php浏览器服务,不要输入任何密码和下载