secretdropvault

package module
v0.1.0 Latest Latest
Warning

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

Go to latest
Published: Feb 22, 2026 License: MIT Imports: 9 Imported by: 0

README

Version Go Run go tests Run golangci-lint codecov Go Reference Go Report Card

secretdropvault

AES-256-GCM encryption with HKDF-SHA256 key derivation — the crypto engine behind SecretDrop.

Zero dependencies beyond the Go standard library.


Security Model

  1. A random 256-bit key is generated per secret
  2. HKDF-SHA256 derives a unique encryption key per recipient (bound to their email address as the info parameter)
  3. AES-256-GCM provides authenticated encryption with a random nonce
  4. The random key is carried only in the URL fragment (# portion) — never sent to the server or stored in the database
  5. Email addresses are stored as SHA-256 hashes — never in plaintext

Requirements

Tool Version
Go 1.26+

Installation

go get github.com/bilustek/secretdropvault

Usage

package main

import (
	"fmt"
	"log"

	"github.com/bilustek/secretdropvault"
)

func main() {
	// 1. Generate a random key
	randomKey, err := secretdropvault.GenerateRandomKey()
	if err != nil {
		log.Fatal(err)
	}

	// 2. Derive an encryption key bound to the recipient
	recipient := "[email protected]"
	encKey, err := secretdropvault.DeriveKey(randomKey, recipient)
	if err != nil {
		log.Fatal(err)
	}

	// 3. Encrypt
	secret := []byte("DB_PASSWORD=super-secret")
	ciphertext, nonce, err := secretdropvault.Encrypt(encKey, secret)
	if err != nil {
		log.Fatal(err)
	}

	// 4. Encode the random key for URL transport
	encoded := secretdropvault.EncodeKey(randomKey)
	fmt.Println("URL key fragment:", encoded)

	// --- recipient side ---

	// 5. Decode the key from the URL fragment
	decodedKey, err := secretdropvault.DecodeKey(encoded)
	if err != nil {
		log.Fatal(err)
	}

	// 6. Re-derive the encryption key
	decKey, err := secretdropvault.DeriveKey(decodedKey, recipient)
	if err != nil {
		log.Fatal(err)
	}

	// 7. Decrypt
	plaintext, err := secretdropvault.Decrypt(decKey, ciphertext, nonce)
	if err != nil {
		log.Fatal(err)
	}

	fmt.Println("Decrypted:", string(plaintext))
}
Hashing emails
hash := secretdropvault.HashEmail("[email protected]")
// hex-encoded SHA-256, safe to store in DB
Generating tokens
token, err := secretdropvault.GenerateToken()
// base64url-encoded random token (16 bytes)

API

Function Description
GenerateRandomKey() Generates a 32-byte cryptographically secure random key
GenerateToken() Generates a random base64url-encoded token
DeriveKey(key, info) Derives a 32-byte key via HKDF-SHA256
Encrypt(key, plaintext) AES-256-GCM encryption, returns ciphertext + nonce
Decrypt(key, ciphertext, nonce) AES-256-GCM decryption
HashEmail(email) Hex-encoded SHA-256 hash
EncodeKey(key) Base64url encode (no padding)
DecodeKey(encoded) Base64url decode (no padding)

Contributor(s)


Contribute

All PR's are welcome!

  1. fork (https://github.com/bilustek/secretdropvault/fork)
  2. Create your branch (git checkout -b my-feature)
  3. commit yours (git commit -am 'add some functionality')
  4. push your branch (git push origin my-feature)
  5. Than create a new Pull Request!

License

This project is licensed under MIT


This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the code of conduct.

Documentation

Overview

Package secretdropvault provides AES-256-GCM encryption with HKDF-SHA256 key derivation. It is the cryptographic engine behind SecretDrop — a one-time secret sharing service.

Security model:

  • A random 256-bit key is generated per secret.
  • HKDF-SHA256 derives a unique encryption key per recipient (bound to their email).
  • AES-256-GCM provides authenticated encryption with a random nonce.
  • The random key is carried only in the URL fragment (never sent to the server).
  • Email addresses are stored as SHA-256 hashes (never in plaintext).

Index

Constants

View Source
const (
	// KeySize is the AES-256 key size in bytes.
	KeySize = 32

	// TokenSize is the number of random bytes used to generate a token.
	TokenSize = 16
)

Variables

This section is empty.

Functions

func DecodeKey

func DecodeKey(encoded string) ([]byte, error)

DecodeKey decodes a base64url-encoded key (no padding).

func Decrypt

func Decrypt(key, ciphertext, nonce []byte) ([]byte, error)

Decrypt decrypts ciphertext using AES-256-GCM with the given key and nonce.

func DeriveKey

func DeriveKey(randomKey []byte, info string) ([]byte, error)

DeriveKey uses HKDF-SHA256 to derive a KeySize-byte key from the input key material and an info string (typically the recipient's email address).

func EncodeKey

func EncodeKey(key []byte) string

EncodeKey encodes a key as base64url (no padding) for URL fragment usage.

func Encrypt

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

Encrypt encrypts plaintext using AES-256-GCM with the given key. Returns ciphertext (with appended authentication tag) and nonce.

func GenerateRandomKey

func GenerateRandomKey() ([]byte, error)

GenerateRandomKey creates a cryptographically secure random key of KeySize bytes.

func GenerateToken

func GenerateToken() (string, error)

GenerateToken creates a random token encoded as base64url (no padding). The token is TokenSize random bytes, base64url-encoded.

func HashEmail

func HashEmail(email string) string

HashEmail returns the hex-encoded SHA-256 hash of an email address.

Types

This section is empty.

Jump to

Keyboard shortcuts

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