Documentation ¶
Overview ¶
Package adiantum wraps an SQLite VFS to offer encryption at rest.
The "adiantum" vfs.VFS wraps the default VFS using the Adiantum tweakable, length-preserving encryption.
Importing package adiantum registers that VFS:
import _ "github.com/ncruces/go-sqlite3/vfs/adiantum"
To open an encrypted database you need to provide key material.
The simplest way to do that is to specify the key through an URI parameter:
- key: key material in binary (32 bytes)
- hexkey: key material in hex (64 hex digits)
- textkey: key material in text (any length)
However, this makes your key easily accessible to other parts of your application (e.g. through vfs.Filename.URIParameters).
To avoid this, invoke any of the following PRAGMAs immediately after opening a connection:
PRAGMA key='D41d8cD98f00b204e9800998eCf8427e'; PRAGMA hexkey='e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855'; PRAGMA textkey='your-secret-key';
For an ATTACH-ed database, you must specify the schema name:
ATTACH DATABASE 'demo.db' AS demo; PRAGMA demo.textkey='your-secret-key';
Index ¶
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func Register ¶
func Register(name string, base vfs.VFS, cipher HBSHCreator)
Register registers an encrypting VFS, wrapping a base VFS, and possibly using a custom HBSH cipher construction. To use the default Adiantum construction, set cipher to nil.
Example (Hpolyc) ¶
//go:build (linux || darwin || windows || freebsd || openbsd || netbsd || dragonfly || illumos || sqlite3_flock) && !sqlite3_nosys package main import ( "crypto/rand" "log" "os" "github.com/ncruces/go-sqlite3" "github.com/ncruces/go-sqlite3/vfs" "github.com/ncruces/go-sqlite3/vfs/adiantum" "golang.org/x/crypto/argon2" "lukechampine.com/adiantum/hbsh" "lukechampine.com/adiantum/hpolyc" ) func main() { adiantum.Register("hpolyc", vfs.Find(""), hpolycCreator{}) db, err := sqlite3.Open("file:demo.db?vfs=hpolyc" + "&textkey=correct+horse+battery+staple") if err != nil { log.Fatal(err) } defer os.Remove("./demo.db") defer db.Close() } type hpolycCreator struct{} // HBSH creates an HBSH cipher given a key. func (hpolycCreator) HBSH(key []byte) *hbsh.HBSH { if len(key) != 32 { // Key is not appropriate, return nil. return nil } return hpolyc.New(key) } // KDF gets a key from a secret. func (hpolycCreator) KDF(secret string) []byte { if secret == "" { // No secret is given, generate a random key. key := make([]byte, 32) n, _ := rand.Read(key) return key[:n] } // Hash the secret with a KDF. return argon2.IDKey([]byte(secret), []byte("hpolyc"), 3, 64*1024, 4, 32) }
Output:
Types ¶
type HBSHCreator ¶
type HBSHCreator interface { // KDF derives an HBSH key from a secret. // If no secret is given, a random key is generated. KDF(secret string) (key []byte) // HBSH creates an HBSH cipher given a key. // If key is not appropriate, nil is returned. HBSH(key []byte) *hbsh.HBSH }
HBSHCreator creates an hbsh.HBSH cipher given key material.