crypt

package module
v0.0.27 Latest Latest
Warning

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

Go to latest
Published: Sep 9, 2026 License: MIT Imports: 13 Imported by: 8

README

crypt

Batteries-included encryption for Go: AEAD ciphers, RSA, and a ready-made envelope-encryption scheme, all behind a small, hard-to-misuse API.

Go Reference DeepWiki CodeQL

crypt wraps Go's standard crypto packages and golang.org/x/crypto so you can encrypt and decrypt data with well-established primitives without writing the fiddly plumbing yourself. Every function authenticates its output, generates nonces for you, and returns plain []byte / string values.

The whole library on one page: pick a path at the top, find the package and file it lives in, then the one naming pattern the ciphers share.

Features

  • AES-GCM: AES-128/192/256 authenticated encryption.
  • ChaCha20-Poly1305: fast AEAD with a 96-bit nonce.
  • XChaCha20-Poly1305: AEAD with a 192-bit nonce, safe for huge numbers of messages under one key.
  • RSA-OAEP: public-key encryption with SHA-256 (default) or SHA-512.
  • Base64 helpers: Std, RawStd, URL and RawURL encoders/decoders.
  • envelope subpackage: a complete KEK/DEK envelope-encryption scheme for protecting many records under a single rotatable secret.
  • Streaming: chunked XChaCha20-Poly1305 for files that do not fit in memory, with constant memory use and no size ceiling.
  • Length hiding: pad a payload before sealing so its size stops identifying it.

Install

go get github.com/pilinux/crypt

Requires Go 1.25+. The only external dependency is golang.org/x/crypto.

Quick start

Symmetric encryption (AES-256-GCM)
package main

import (
	"crypto/rand"
	"fmt"

	"golang.org/x/crypto/argon2"

	"github.com/pilinux/crypt"
)

func main() {
	// 1. Derive a 32-byte key. crypt never derives keys for you;
	//    bring your own KDF (here: Argon2id over a passphrase).
	salt := make([]byte, 16)
	if _, err := rand.Read(salt); err != nil {
		panic(err)
	}
	key := argon2.IDKey([]byte("s3cr3t-passphrase"), salt, 2, 64*1024, 2, 32)

	// 2. Encrypt. A random nonce is generated and prepended to the
	//    ciphertext, so you only ever store a single blob.
	ciphertext, err := crypt.EncryptAesGcmWithNonceAppended(key, "attack at dawn")
	if err != nil {
		panic(err)
	}

	// 3. Decrypt. This also verifies authenticity: any tampering
	//    (or a wrong key) returns an error instead of garbage.
	plaintext, err := crypt.DecryptAesGcmWithNonceAppended(key, ciphertext)
	if err != nil {
		panic(err)
	}

	fmt.Println(plaintext) // attack at dawn
}

Every symmetric cipher follows the same four-way naming pattern, so once you know one you know them all:

Variant Input / output Nonce
Encrypt<Cipher> string returned separately
EncryptByte<Cipher> []byte returned separately
Encrypt<Cipher>WithNonceAppended string prepended to ciphertext
EncryptByte<Cipher>WithNonceAppended []byte prepended to ciphertext

Swap EncryptAesGcm for EncryptXChacha20poly1305 (or the ChaCha20 variant) to change algorithms; the shape is identical.

Public-key encryption (RSA-OAEP)
// publicKeyPEM / privateKeyPEM are strings loaded from .pem files
// (PKIX "PUBLIC KEY" and PKCS#8 "PRIVATE KEY" blocks; see below).

enc := crypt.NewEncoder(publicKeyPEM)
if enc.Err != nil {
	panic(enc.Err) // the constructor reports PEM problems via .Err
}

ciphertext, err := enc.EncryptRSA("attack at dawn")
if err != nil {
	panic(err)
}

dec := crypt.NewDecoder(privateKeyPEM)
if dec.Err != nil {
	panic(dec.Err)
}

plaintext, err := dec.DecryptRSA(ciphertext)
if err != nil {
	panic(err)
}

// Want SHA-512 instead of the SHA-256 default? Set it on both sides:
//   enc.HashAlg = crypt.SHA512
//   dec.HashAlg = crypt.SHA512
Envelope encryption (many records, one rotatable secret)

Use the envelope subpackage when you need to protect lots of items (rows, files, fields) and be able to rotate the top-level secret without re-encrypting everything.

package main

import (
	"fmt"
	"os"

	"github.com/pilinux/crypt/envelope"
)

func main() {
	// Configure once with your app's domain-separation labels.
	scheme := envelope.New(envelope.Config{
		KEKLabel:    "myapp:kek:v1",
		SubKeyLabel: "myapp:data-subkey:v1",
	})

	// Bootstrap: derive a key-encryption key (KEK) from a rotatable secret,
	// then generate a master key and store it *wrapped*. (Errors omitted
	// for brevity; handle them in real code.)
	// The secret must be machine-generated randomness, >= 32 chars
	// (e.g. `openssl rand -hex 32`), never a human-chosen passphrase.
	kek, _ := scheme.DeriveKEK(os.Getenv("ENCRYPTION_SECRET"))
	masterKey, _ := envelope.GenerateMasterKey()
	wrapped, _ := envelope.WrapKey(kek, masterKey) // persist `wrapped`, not masterKey
	_ = wrapped

	// Per item: seal to a base64 token, then open it back.
	token, _ := scheme.SealString(masterKey, "top secret")
	plain, _ := scheme.OpenString(masterKey, token)

	fmt.Println(plain) // top secret

	// Optional context binding: authenticate the record/field the token
	// belongs to, so valid tokens cannot be swapped between rows.
	bound, _ := scheme.SealStringAAD(masterKey, "top secret", []byte("user:42:note"))
	_, err := scheme.OpenStringAAD(masterKey, bound, []byte("user:7:note"))
	fmt.Println(err != nil) // wrong context fails to decrypt
}

Under the hood every item gets a fresh per-item sub-key (HKDF) and its own random nonce, so a nonce can never repeat under the same key. The envelope header is authenticated, and every Seal*/Open* function has an AAD variant that additionally authenticates caller-supplied context.

Large files (streaming)

Seal*/Open* hold the whole item in memory. For data that does not fit, such as a 10 GB backup, a 100 GB disk image or an upload of unknown length, the same scheme also streams, sealing one chunk at a time:

// Whole files, in constant memory. The destination must not exist yet.
n, err := scheme.SealFileAAD(masterKey, "backup.tar.enc", "backup.tar", []byte("backup.tar"))
_, err = scheme.OpenFileAAD(masterKey, "restored.tar", "backup.tar.enc", []byte("backup.tar"))

// Or plug into any io.Reader / io.Writer: HTTP bodies, S3 objects, pipes.
_, err = scheme.SealStream(masterKey, w, r) // io.Writer <- io.Reader
_, err = scheme.OpenStream(masterKey, w, r)

// Or take the writer/reader themselves and compose freely.
sw, err := scheme.SealWriter(masterKey, dst) // io.WriteCloser
defer sw.Abort()                             // no-op once Close has succeeded
_, err = io.Copy(sw, src)
err = sw.Close() // seals the final chunk; the stream is only complete after this

sr, err := scheme.OpenReader(masterKey, src) // io.Reader
_, err = io.Copy(dst, sr)

Each chunk (1 MiB by default, Config.ChunkSize) is sealed under the same per-stream sub-key with the nonce noncePrefix || counter || finalFlag, so chunks cannot be reordered, duplicated, dropped, or the stream cut short: a truncated file fails to open instead of decrypting to truncated plaintext. Every stream records its own chunk size, so changing ChunkSize later never orphans sealed data.

What it costs. A stream holds exactly one chunk in memory whatever the input size, and that buffer is allocated once per stream and reused, so nothing is allocated per chunk: sealing a 100 GB file costs the same handful of allocations as sealing 1 KB. On the wire:

sealed = 37 + plaintext + 16 * chunks     chunks = ceil(plaintext / ChunkSize), min 1

That is a 37-byte header plus one 16-byte tag per chunk, so a 10 GB file at the default 1 MiB chunk size grows by 160 KiB, about 0.0015%. Larger chunks mean less overhead and more memory per stream; smaller chunks the reverse. MinChunkSize (1 KiB) keeps the worst case under 2%, and MaxChunkSize (64 MiB) is the widest the format allows. A reader allocates whatever the header names before anything authenticates, so a service that only writes small chunks should say so with Config.MaxAcceptedChunkSize rather than accept 64 MiB per concurrent open from a stranger.

Hiding the file length

A sealed stream states its chunk size in the clear, so the exact plaintext length follows from the file size. The padded pair pads the payload first, inside the encryption:

// Files: the payload size comes from a Stat.
n, err := scheme.SealPaddedFileAAD(masterKey, "doc.enc", "doc.pdf", []byte("doc"))
_, err = scheme.OpenPaddedFileAAD(masterKey, "doc.out", "doc.enc", []byte("doc"))

// Anything else: an io.Reader plus its length. Nothing is staged on disk.
_, err = scheme.SealPaddedStream(masterKey, w, r, size) // io.Writer <- io.Reader
_, err = scheme.OpenPaddedStream(masterKey, w, r)

Both produce the same format, so a padded blob sealed one way opens the other. Padding costs no memory: the frame, the payload and the zero padding are pulled through the chunk sealer as it asks for them, so a padded 10 GB upload is sealed on the fly exactly like an unpadded one. The length is the one thing needed in advance, since it is written ahead of the payload and fixes the bucket: pass a Content-Length, a len(), or use the file form. A source that then delivers a different number of bytes fails with ErrSourceSize at the payload boundary, before a single byte of padding is written, which is what makes size safe to accept from an untrusted peer.

The payload is framed as version(1) || realLen(8) || payload || zero padding and rounded up to a Padmé bucket (PaddedSize), destroying 12 to 25 bits of the length for about 1.4% extra storage. Measured over 162,524 real files: of those above 1 MB, 61% are uniquely identified by their exact size, 3.9% after padding. OpenPaddedFile reads the padding back and authenticates it before discarding it, so truncation inside the padding still fails.

When the length is not knowable up front, as with an HTML multipart upload (no per-part Content-Length, and the file is chosen after the page loads), seal it unpadded and pad it afterwards:

// Request path: SealStream takes no size at all.
n, err := scheme.SealStreamAAD(masterKey, dst, part, aad)

// Background pass: open the unpadded object and re-seal it padded.
// n comes from stage 1 here, or from the sealed size (see below).
r, err := scheme.OpenReaderAAD(masterKey, src, aad)
_, err = scheme.SealPaddedStreamAAD(masterKey, dst2, r, n, aad)

Nothing has to carry n between the two stages: an unpadded stream is StreamHeaderSize + n + 16*ceil(n/ChunkSize) bytes, and PlaintextLen inverts that, so the sealed size gives the length back. A crash then leaves a valid sealed object rather than a lost upload. Which objects still owe a pass is the one thing this does not tell you for free: padded and plain blobs are deliberately indistinguishable, so an unpadded object opened as padded fails with ErrStreamAuth, exactly like a wrong key. Retry with OpenStream to identify it, or track the state alongside the object. The two formats are told apart by a format tag that every chunk authenticates and no file stores, bound to the caller's AAD as one fixed-width digest, so neither reader can be talked into accepting the other's stream whatever AAD it is handed.

Only the length is hidden. File names, timestamps and access patterns leak independently; use RandomHex names if that matters.

Choosing an algorithm

If you want to… Reach for Key
Encrypt data with a key you already hold or derive AES-256-GCM or XChaCha20-Poly1305 32 bytes
Encrypt many messages under one key without nonce worries XChaCha20-Poly1305 32 bytes
Let someone encrypt to you using your public key RSA-OAEP PEM key pair
Protect many records under one rotatable secret envelope subpackage derived
Encrypt a file too big to hold in memory envelope streaming (SealFile, SealWriter) derived
Stop a file's size from identifying it envelope padding (SealPaddedFile, SealPaddedStream) derived

API at a glance

Area Key functions
AES-GCM (aes.go) EncryptAesGcm / DecryptAesGcm (+ Byte and WithNonceAppended variants)
ChaCha20-Poly1305 (chaCha20.go) EncryptChacha20poly1305 / DecryptChacha20poly1305 (96-bit nonce)
XChaCha20-Poly1305 (chaCha20.go) EncryptXChacha20poly1305 / DecryptXChacha20poly1305 (192-bit nonce)
RSA-OAEP (rsa.go) Encoder.EncryptRSA / Decoder.DecryptRSA (+ Byte variants)
Base64 (base64.go) Encoder.ToBase64* / Decoder.FromBase64* (Std, RawStd, URL, RawURL)
Envelope (envelope/) Scheme.Seal*/Open* (+ AAD variants), DeriveKEK, WrapKey/UnwrapKey, Zero, Sha256Hex, RandomHex
Envelope streaming (envelope/) Scheme.SealFile/OpenFile, SealStream/OpenStream, SealWriter/OpenReader/StreamWriter.Abort (+ AAD variants), StreamHeaderSize, PlaintextLen
Envelope padding (envelope/) Scheme.SealPaddedFile/OpenPaddedFile, SealPaddedStream/OpenPaddedStream (+ AAD variants), PaddedSize

The ChaCha20/XChaCha20 Byte...WithNonceAppended functions also come in ...AAD forms that bind caller-supplied associated data (authenticated, not encrypted) into the ciphertext.

Full, always-current reference lives on pkg.go.dev.

Runnable examples

Each folder under _example is a standalone program you can run with go run ./_example/<name>:

Generate RSA keys

RSA works with a PKIX public key (PUBLIC KEY) and a PKCS#8 private key (PRIVATE KEY): exactly what these OpenSSL commands produce.

RSA-2048 (256-byte)
openssl genpkey -algorithm RSA -out private-key.pem -pkeyopt rsa_keygen_bits:2048
openssl rsa -in private-key.pem -pubout -out public-key.pem
RSA-3072 (384-byte)
openssl genpkey -algorithm RSA -out private-key.pem -pkeyopt rsa_keygen_bits:3072
openssl rsa -in private-key.pem -pubout -out public-key.pem
RSA-4096 (512-byte)
openssl genpkey -algorithm RSA -out private-key.pem -pkeyopt rsa_keygen_bits:4096
openssl rsa -in private-key.pem -pubout -out public-key.pem

Security notes

  • Bring your own key derivation. crypt encrypts with the key you give it; it never derives one. Use Argon2id for passwords and HKDF for high-entropy secrets (the envelope subpackage does the latter for you).
  • The envelope secret must be machine-generated. DeriveKEK uses HKDF, which does no password stretching: generate ENCRYPTION_SECRET with openssl rand -hex 32 (or similar) and never use a human-chosen passphrase. The floor is 32 bytes, which is what len(secret) measures. A guessable secret can be brute-forced offline from the wrapped master key.
  • Key sizes. AES accepts 16/24/32-byte keys; ChaCha20 and XChaCha20 require exactly 32 bytes.
  • Never reuse a (key, nonce) pair. Nonces come from crypto/rand. When encrypting many items under one key, prefer XChaCha20-Poly1305 or the envelope scheme, which give each item its own key or a large random nonce.
  • Everything is authenticated. All AEAD modes and RSA-OAEP fail closed: tampered ciphertext or a wrong key returns an error, never partial plaintext. In the envelope package that error is a sentinel: ErrEnvelopeAuth for a token or a wrapped key, ErrStreamAuth for a stream. Neither says which of "wrong key", "wrong AAD" or "altered bytes" it was, since telling those apart is what an attacker probing a datastore would want.
  • Fail closed on bad input, never panic. The Decrypt… functions that take a nonce directly validate its length (12 bytes for AES-GCM and ChaCha20-Poly1305, 24 for XChaCha20-Poly1305) and return an error on a mismatch instead of letting the underlying cipher panic.
  • Per-message size limit. A single message is capped by the underlying AEAD: roughly 256 GiB for ChaCha20/XChaCha20-Poly1305 and 64 GiB for AES-GCM. Anything larger returns an error rather than panicking. These bounds sit far above any realistic payload; for data that big use the envelope streaming API, which chunks it and lifts the ceiling.
  • A stream is only trustworthy once it ends. The streaming API authenticates every chunk before releasing it, but a consumer that acts on partial output has acted on data whose stream may still fail. Treat the destination as unusable until the call returns without error. StreamWriter.Close finalizes a stream that has not failed and refuses one that has, so a source that quit part-way cannot be closed into a valid short stream. Use StreamWriter.Abort for the case nothing failed and you simply do not want the stream: defer sw.Abort() costs nothing once Close has succeeded.
  • Ciphertext reveals its plaintext length. Both formats store enough in the clear to recover it exactly: blob - 58 for a token, size - 37 - 16*chunks for a stream. Content, key and context stay hidden, but size alone can identify a known file. Use SealPaddedFile for files and SealPaddedStream for everything else, or seal unpadded and pad in a second pass when the length is not known up front; SealInt64 is already fixed-width, and other tokens need padding before you seal them.
  • RSA key formats. The public key must be a PKIX PUBLIC KEY block and the private key a PKCS#8 PRIVATE KEY block. Always check .Err right after NewEncoder / NewDecoder.

Development

go test -race -cover ./...   # unit tests, race detector, coverage
go vet ./...                 # static analysis
golangci-lint run ./...      # aggregate linters

License

MIT. See LICENSE.

Documentation

Overview

Package crypt provides small, hard-to-misuse helpers for encrypting and decrypting data with well-established cryptographic primitives, wrapping the standard library and golang.org/x/crypto.

It offers:

  • AES-GCM authenticated encryption (AES-128/192/256);
  • ChaCha20-Poly1305 (96-bit nonce) and XChaCha20-Poly1305 (192-bit nonce) AEAD;
  • RSA-OAEP public-key encryption with SHA-256 or SHA-512;
  • Base64 encoding helpers (standard, raw, and URL alphabets).

Symmetric API conventions

Each symmetric cipher exposes a consistent set of functions: a string form (for example EncryptAesGcm) and a byte form (EncryptByteAesGcm), and each of those has a plain variant that returns the nonce separately plus a WithNonceAppended variant that prepends the freshly generated nonce to the ciphertext, so the whole message can be stored as a single value. Every encryption generates its nonce with crypto/rand, and every decryption authenticates the ciphertext, returning an error on tampering or a wrong key.

The package does not derive keys. Callers pass a key of the correct length (AES accepts 16, 24, or 32 bytes; ChaCha20 and XChaCha20 require 32) and should derive keys from passwords with a KDF such as Argon2id.

Public-key and Base64

RSA-OAEP and the Base64 helpers are methods on the Encoder and Decoder types, which are built from PEM-encoded keys with NewEncoder and NewDecoder.

Higher-level scheme

For envelope encryption with a key hierarchy and a rotatable secret (useful for protecting many records at rest), see the subpackage github.com/pilinux/crypt/envelope.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func DecryptAesGcm

func DecryptAesGcm(key, nonce, ciphertext []byte) (text string, err error)

DecryptAesGcm decrypts and authenticates the given message with AES in GCM mode using the given 128, 192 or 256-bit key and 96-bit nonce.

func DecryptAesGcmWithNonceAppended added in v0.0.10

func DecryptAesGcmWithNonceAppended(key, ciphertext []byte) (text string, err error)

DecryptAesGcmWithNonceAppended decrypts and authenticates the given ciphertext with AES in GCM mode using the given 128, 192 or 256-bit key. It expects the ciphertext along with the nonce [ciphertext = nonce + ciphertext].

func DecryptByteAesGcm added in v0.0.21

func DecryptByteAesGcm(key, nonce, ciphertext []byte) (plaintext []byte, err error)

DecryptByteAesGcm decrypts and authenticates the given message with AES in GCM mode using the given 128, 192 or 256-bit key and 96-bit nonce.

func DecryptByteAesGcmWithNonceAppended added in v0.0.21

func DecryptByteAesGcmWithNonceAppended(key, ciphertext []byte) (plaintext []byte, err error)

DecryptByteAesGcmWithNonceAppended decrypts and authenticates the given ciphertext with AES in GCM mode using the given 128, 192 or 256-bit key. It expects the ciphertext along with the nonce [ciphertext = nonce + ciphertext].

func DecryptByteChacha20poly1305 added in v0.0.11

func DecryptByteChacha20poly1305(key, nonce, ciphertext []byte) (plaintext []byte, err error)

DecryptByteChacha20poly1305 decrypts and authenticates the given ciphertext with ChaCha20-Poly1305 AEAD using the given 256-bit key and 96-bit nonce.

func DecryptByteChacha20poly1305WithNonceAppended added in v0.0.11

func DecryptByteChacha20poly1305WithNonceAppended(key, ciphertext []byte) (plaintext []byte, err error)

DecryptByteChacha20poly1305WithNonceAppended decrypts and authenticates the given ciphertext with ChaCha20-Poly1305 AEAD using the given 256-bit key and 96-bit nonce. It expects the ciphertext along with the nonce [ciphertext = nonce + ciphertext].

func DecryptByteChacha20poly1305WithNonceAppendedAAD added in v0.0.22

func DecryptByteChacha20poly1305WithNonceAppendedAAD(key, ciphertext, additionalData []byte) (plaintext []byte, err error)

DecryptByteChacha20poly1305WithNonceAppendedAAD decrypts and authenticates the given ciphertext with ChaCha20-Poly1305 AEAD using the given 256-bit key and 96-bit nonce, verifying additionalData (AAD) against the value supplied at encryption. Decryption fails if the AAD differs. A nil AAD makes this equivalent to DecryptByteChacha20poly1305WithNonceAppended. It expects the ciphertext along with the nonce [ciphertext = nonce + ciphertext].

func DecryptByteXChacha20poly1305 added in v0.0.11

func DecryptByteXChacha20poly1305(key, nonce, ciphertext []byte) (plaintext []byte, err error)

DecryptByteXChacha20poly1305 decrypts and authenticates the given ciphertext with XChaCha20-Poly1305 AEAD using the given 256-bit key and 192-bit nonce.

func DecryptByteXChacha20poly1305WithNonceAppended added in v0.0.11

func DecryptByteXChacha20poly1305WithNonceAppended(key, ciphertext []byte) (plaintext []byte, err error)

DecryptByteXChacha20poly1305WithNonceAppended decrypts and authenticates the given ciphertext with XChaCha20-Poly1305 AEAD using the given 256-bit key and 192-bit nonce. It expects the ciphertext along with the nonce [ciphertext = nonce + ciphertext].

func DecryptByteXChacha20poly1305WithNonceAppendedAAD added in v0.0.22

func DecryptByteXChacha20poly1305WithNonceAppendedAAD(key, ciphertext, additionalData []byte) (plaintext []byte, err error)

DecryptByteXChacha20poly1305WithNonceAppendedAAD decrypts and authenticates the given ciphertext with XChaCha20-Poly1305 AEAD using the given 256-bit key and 192-bit nonce, verifying additionalData (AAD) against the value supplied at encryption. Decryption fails if the AAD differs. A nil AAD makes this equivalent to DecryptByteXChacha20poly1305WithNonceAppended. It expects the ciphertext along with the nonce [ciphertext = nonce + ciphertext].

func DecryptChacha20poly1305

func DecryptChacha20poly1305(key, nonce, ciphertext []byte) (text string, err error)

DecryptChacha20poly1305 decrypts and authenticates the given ciphertext with ChaCha20-Poly1305 AEAD using the given 256-bit key and 96-bit nonce.

func DecryptChacha20poly1305WithNonceAppended added in v0.0.10

func DecryptChacha20poly1305WithNonceAppended(key, ciphertext []byte) (text string, err error)

DecryptChacha20poly1305WithNonceAppended decrypts and authenticates the given ciphertext with ChaCha20-Poly1305 AEAD using the given 256-bit key and 96-bit nonce. It expects the ciphertext along with the nonce [ciphertext = nonce + ciphertext].

func DecryptXChacha20poly1305 added in v0.0.10

func DecryptXChacha20poly1305(key, nonce, ciphertext []byte) (text string, err error)

DecryptXChacha20poly1305 decrypts and authenticates the given ciphertext with XChaCha20-Poly1305 AEAD using the given 256-bit key and 192-bit nonce.

func DecryptXChacha20poly1305WithNonceAppended added in v0.0.10

func DecryptXChacha20poly1305WithNonceAppended(key, ciphertext []byte) (text string, err error)

DecryptXChacha20poly1305WithNonceAppended decrypts and authenticates the given ciphertext with XChaCha20-Poly1305 AEAD using the given 256-bit key and 192-bit nonce. It expects the ciphertext along with the nonce [ciphertext = nonce + ciphertext].

func EncryptAesGcm

func EncryptAesGcm(key []byte, text string) (ciphertext []byte, nonce []byte, err error)

EncryptAesGcm encrypts and authenticates the given message (string) with AES in GCM mode using the given 128, 192 or 256-bit key.

func EncryptAesGcmWithNonceAppended added in v0.0.10

func EncryptAesGcmWithNonceAppended(key []byte, text string) (ciphertext []byte, err error)

EncryptAesGcmWithNonceAppended encrypts and authenticates the given message (string) with AES in GCM mode using the given 128, 192 or 256-bit key. It appends the ciphertext to the nonce [ciphertext = nonce + ciphertext].

func EncryptByteAesGcm added in v0.0.21

func EncryptByteAesGcm(key []byte, input []byte) (ciphertext []byte, nonce []byte, err error)

EncryptByteAesGcm encrypts and authenticates the given message (bytes) with AES in GCM mode using the given 128, 192 or 256-bit key.

func EncryptByteAesGcmWithNonceAppended added in v0.0.21

func EncryptByteAesGcmWithNonceAppended(key []byte, input []byte) (ciphertext []byte, err error)

EncryptByteAesGcmWithNonceAppended encrypts and authenticates the given message (bytes) with AES in GCM mode using the given 128, 192 or 256-bit key. It appends the ciphertext to the nonce [ciphertext = nonce + ciphertext].

func EncryptByteChacha20poly1305 added in v0.0.11

func EncryptByteChacha20poly1305(key []byte, input []byte) (ciphertext []byte, nonce []byte, err error)

EncryptByteChacha20poly1305 encrypts and authenticates the given message (bytes) with ChaCha20-Poly1305 AEAD using the given 256-bit key and 96-bit nonce.

func EncryptByteChacha20poly1305WithNonceAppended added in v0.0.11

func EncryptByteChacha20poly1305WithNonceAppended(key []byte, input []byte) (ciphertext []byte, err error)

EncryptByteChacha20poly1305WithNonceAppended encrypts and authenticates the given message (bytes) with ChaCha20-Poly1305 AEAD using the given 256-bit key and 96-bit nonce. It appends the ciphertext to the nonce [ciphertext = nonce + ciphertext].

func EncryptByteChacha20poly1305WithNonceAppendedAAD added in v0.0.22

func EncryptByteChacha20poly1305WithNonceAppendedAAD(key, input, additionalData []byte) (ciphertext []byte, err error)

EncryptByteChacha20poly1305WithNonceAppendedAAD encrypts and authenticates the given message (bytes) with ChaCha20-Poly1305 AEAD using the given 256-bit key and 96-bit nonce, and additionally authenticates additionalData (AAD). The AAD is neither encrypted nor included in the output; the identical bytes must be supplied at decryption. A nil AAD makes this equivalent to EncryptByteChacha20poly1305WithNonceAppended. It appends the ciphertext to the nonce [ciphertext = nonce + ciphertext].

func EncryptByteXChacha20poly1305 added in v0.0.11

func EncryptByteXChacha20poly1305(key []byte, input []byte) (ciphertext []byte, nonce []byte, err error)

EncryptByteXChacha20poly1305 encrypts and authenticates the given message (bytes) with XChaCha20-Poly1305 AEAD using the given 256-bit key and 192-bit nonce.

func EncryptByteXChacha20poly1305WithNonceAppended added in v0.0.11

func EncryptByteXChacha20poly1305WithNonceAppended(key []byte, input []byte) (ciphertext []byte, err error)

EncryptByteXChacha20poly1305WithNonceAppended encrypts and authenticates the given message (bytes) with XChaCha20-Poly1305 AEAD using the given 256-bit key and 192-bit nonce. It appends the ciphertext to the nonce [ciphertext = nonce + ciphertext].

func EncryptByteXChacha20poly1305WithNonceAppendedAAD added in v0.0.22

func EncryptByteXChacha20poly1305WithNonceAppendedAAD(key, input, additionalData []byte) (ciphertext []byte, err error)

EncryptByteXChacha20poly1305WithNonceAppendedAAD encrypts and authenticates the given message (bytes) with XChaCha20-Poly1305 AEAD using the given 256-bit key and 192-bit nonce, and additionally authenticates additionalData (AAD). The AAD is neither encrypted nor included in the output; the identical bytes must be supplied at decryption. A nil AAD makes this equivalent to EncryptByteXChacha20poly1305WithNonceAppended. It appends the ciphertext to the nonce [ciphertext = nonce + ciphertext].

func EncryptChacha20poly1305

func EncryptChacha20poly1305(key []byte, text string) (ciphertext []byte, nonce []byte, err error)

EncryptChacha20poly1305 encrypts and authenticates the given message (string) with ChaCha20-Poly1305 AEAD using the given 256-bit key and 96-bit nonce.

func EncryptChacha20poly1305WithNonceAppended added in v0.0.10

func EncryptChacha20poly1305WithNonceAppended(key []byte, text string) (ciphertext []byte, err error)

EncryptChacha20poly1305WithNonceAppended encrypts and authenticates the given message (string) with ChaCha20-Poly1305 AEAD using the given 256-bit key and 96-bit nonce. It appends the ciphertext to the nonce [ciphertext = nonce + ciphertext].

func EncryptXChacha20poly1305 added in v0.0.10

func EncryptXChacha20poly1305(key []byte, text string) (ciphertext []byte, nonce []byte, err error)

EncryptXChacha20poly1305 encrypts and authenticates the given message (string) with XChaCha20-Poly1305 AEAD using the given 256-bit key and 192-bit nonce.

func EncryptXChacha20poly1305WithNonceAppended added in v0.0.10

func EncryptXChacha20poly1305WithNonceAppended(key []byte, text string) (ciphertext []byte, err error)

EncryptXChacha20poly1305WithNonceAppended encrypts and authenticates the given message (string) with XChaCha20-Poly1305 AEAD using the given 256-bit key and 192-bit nonce. It appends the ciphertext to the nonce [ciphertext = nonce + ciphertext].

Types

type Decoder

type Decoder struct {
	// PriKeyBlock is the decoded PEM block of the private key.
	PriKeyBlock *pem.Block
	// HashAlg is the hash used by DecryptRSA; the zero value is SHA256.
	HashAlg HashAlgorithm
	// Err is non-nil when NewDecoder could not decode the private key PEM.
	Err error
}

Decoder holds a PEM-decoded RSA private key and is the entry point for Decoder.DecryptRSA and the Base64 decoding helpers.

Construct one with NewDecoder and check Err before use: the constructor reports a bad PEM input on the Err field instead of returning an error.

func NewDecoder

func NewDecoder(privateKeyPEM string) *Decoder

NewDecoder decodes a PEM-encoded RSA private key (a PKCS#8 "PRIVATE KEY" block) and returns a Decoder for it. It never returns nil; if the input is not a valid private-key PEM block, the returned Decoder has its Err field set, so callers should check Err before calling DecryptRSA.

func (*Decoder) DecryptByteRSA added in v0.0.21

func (d *Decoder) DecryptByteRSA(ciphertext []byte) (plaintext []byte, err error)

DecryptByteRSA decrypts the given message with RSA-OAEP and using SHA-256 (default) or SHA-512.

func (*Decoder) DecryptRSA

func (d *Decoder) DecryptRSA(ciphertext []byte) (text string, err error)

DecryptRSA decrypts the given message with RSA-OAEP and using SHA-256 (default) or SHA-512.

func (*Decoder) FromBase64RawStd

func (d *Decoder) FromBase64RawStd(text string) ([]byte, error)

FromBase64RawStd decodes an unpadded Base64 string produced with the standard alphabet (RFC 4648 section 3.2) back into binary data.

func (*Decoder) FromBase64RawURL

func (d *Decoder) FromBase64RawURL(text string) ([]byte, error)

FromBase64RawURL decodes an unpadded Base64 string produced with the URL- and filename-safe alphabet (RFC 4648 section 5) back into binary data.

func (*Decoder) FromBase64Std

func (d *Decoder) FromBase64Std(text string) ([]byte, error)

FromBase64Std decodes a Base64 string produced with the standard alphabet (RFC 4648) back into binary data.

func (*Decoder) FromBase64URL

func (d *Decoder) FromBase64URL(text string) ([]byte, error)

FromBase64URL decodes a Base64 string produced with the URL- and filename-safe alphabet (RFC 4648 section 5) back into binary data.

type Encoder

type Encoder struct {
	// PubKeyBlock is the decoded PEM block of the public key.
	PubKeyBlock *pem.Block
	// HashAlg is the hash used by EncryptRSA; the zero value is SHA256.
	HashAlg HashAlgorithm
	// Err is non-nil when NewEncoder could not decode the public key PEM.
	Err error
}

Encoder holds a PEM-decoded RSA public key and is the entry point for Encoder.EncryptRSA and the Base64 encoding helpers.

Construct one with NewEncoder and check Err before use: the constructor reports a bad PEM input on the Err field instead of returning an error.

func NewEncoder

func NewEncoder(publicKeyPEM string) *Encoder

NewEncoder decodes a PEM-encoded RSA public key (a "PUBLIC KEY" block) and returns an Encoder for it. It never returns nil; if the input is not a valid public-key PEM block, the returned Encoder has its Err field set, so callers should check Err before calling EncryptRSA.

func (*Encoder) EncryptByteRSA added in v0.0.21

func (e *Encoder) EncryptByteRSA(input []byte) (ciphertext []byte, err error)

EncryptByteRSA encrypts the given message (bytes) with RSA-OAEP and using SHA-256 (default) or SHA-512.

func (*Encoder) EncryptRSA

func (e *Encoder) EncryptRSA(text string) (ciphertext []byte, err error)

EncryptRSA encrypts the given message (string) with RSA-OAEP and using SHA-256 (default) or SHA-512.

func (*Encoder) ToBase64RawStd

func (e *Encoder) ToBase64RawStd(text []byte) string

ToBase64RawStd encodes binary data to a Base64 string using the standard alphabet without padding (RFC 4648 section 3.2): the same as ToBase64Std but with the trailing '=' characters omitted.

func (*Encoder) ToBase64RawURL

func (e *Encoder) ToBase64RawURL(text []byte) string

ToBase64RawURL encodes binary data to a Base64 string using the URL- and filename-safe alphabet without padding (RFC 4648 section 5).

func (*Encoder) ToBase64Std

func (e *Encoder) ToBase64Std(text []byte) string

ToBase64Std encodes binary data to a Base64 string using the standard alphabet (RFC 4648).

func (*Encoder) ToBase64URL

func (e *Encoder) ToBase64URL(text []byte) string

ToBase64URL encodes binary data to a Base64 string using the URL- and filename-safe alphabet (RFC 4648 section 5).

type HashAlgorithm

type HashAlgorithm int

HashAlgorithm selects the hash used by RSA-OAEP in Encoder.EncryptRSA and Decoder.DecryptRSA.

const (
	// SHA256 selects SHA-256. It is the default (the zero value).
	SHA256 HashAlgorithm = iota
	// SHA512 selects SHA-512.
	SHA512
)

Directories

Path Synopsis
_example
aes command
Package main - example usage of AES encryption - decryption
Package main - example usage of AES encryption - decryption
chacha20poly1305 command
Package main - example usage of chacha20poly1305 encryption - decryption
Package main - example usage of chacha20poly1305 encryption - decryption
envelope command
Package main - example usage of the envelope encryption scheme.
Package main - example usage of the envelope encryption scheme.
hashing command
Package main - example implementation of different hashing algorithms
Package main - example implementation of different hashing algorithms
rsa command
Package main - example usage of RSA encryption - decryption
Package main - example usage of RSA encryption - decryption
xchacha20poly1305 command
Package main - example usage of XChaCha20-Poly1305 encryption - decryption
Package main - example usage of XChaCha20-Poly1305 encryption - decryption
Package envelope implements a small, self-contained envelope-encryption scheme layered on top of the low-level AEAD primitives in github.com/pilinux/crypt.
Package envelope implements a small, self-contained envelope-encryption scheme layered on top of the low-level AEAD primitives in github.com/pilinux/crypt.

Jump to

Keyboard shortcuts

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