Skip to content

Security: Time-File/go-file-crypto

Security

docs/security.md

Security Specifications

Detailed security specifications and cryptographic design of go-file-crypto.

Cryptographic Algorithm

AES-256-GCM

This library uses AES-256-GCM (Galois/Counter Mode) exclusively.

Property Value
Algorithm AES-GCM
Key Size 256 bits (32 bytes)
IV/Nonce Size 96 bits (12 bytes)
Authentication Tag 128 bits (16 bytes)

Why AES-256-GCM?

  • Authenticated Encryption - Provides both confidentiality and integrity
  • Hardware Acceleration - AES-NI support in modern CPUs
  • NIST Recommended - Standardized in NIST SP 800-38D
  • Cross-Platform - Identical behavior in Go (crypto/aes, crypto/cipher) and browsers (Web Crypto API)

Key Derivation

Password-Based (PBKDF2)

For password-based encryption, keys are derived using PBKDF2.

Property Value
Algorithm PBKDF2
Hash Function SHA-256
Iterations 100,000
Salt Size 128 bits (16 bytes)
Output Key 256 bits (32 bytes)
derived_key = PBKDF2(password, salt, 100000, SHA-256, 256)

Why 100,000 iterations?

  • Balances security and performance
  • Provides approximately 0.1-0.5 seconds of computation
  • Resistant to brute-force attacks on modern hardware
  • Matches the browser implementation for compatibility

Keyfile-Based

Keyfile-based encryption uses the key directly without derivation.

Property Value
Key Size 256 bits (32 bytes)
Encoding Base64
Source crypto/rand (cryptographically secure)

File Formats

Standard Encryption

Password-Based Format (Marker 0x01)

┌─────────────┬──────────────┬─────────────┬─────────────────────────┐
│ Marker (1B) │ Salt (16B)   │ IV (12B)    │ Ciphertext + Tag (16B)  │
└─────────────┴──────────────┴─────────────┴─────────────────────────┘
Field Size Description
Marker 1 byte 0x01 - identifies password encryption
Salt 16 bytes Random salt for PBKDF2
IV 12 bytes Random initialization vector
Ciphertext Variable AES-GCM encrypted data
Auth Tag 16 bytes GCM authentication tag (appended to ciphertext)

Minimum Size: 45 bytes (1 + 16 + 12 + 16)

Keyfile-Based Format (Marker 0x02)

┌─────────────┬─────────────┬─────────────────────────┐
│ Marker (1B) │ IV (12B)    │ Ciphertext + Tag (16B)  │
└─────────────┴─────────────┴─────────────────────────┘
Field Size Description
Marker 1 byte 0x02 - identifies keyfile encryption
IV 12 bytes Random initialization vector
Ciphertext Variable AES-GCM encrypted data
Auth Tag 16 bytes GCM authentication tag (appended to ciphertext)

Minimum Size: 29 bytes (1 + 12 + 16)


Streaming Encryption

Password-Based Streaming Format (Marker 0x11)

┌─────────────┬────────────┬──────────────┬──────────────┬──────────────┬─────────┐
│ Marker (1B) │ Version(1B)│ ChunkSize(4B)│ Salt (16B)   │ BaseIV (12B) │ Chunks  │
└─────────────┴────────────┴──────────────┴──────────────┴──────────────┴─────────┘
Field Size Description
Marker 1 byte 0x11 - streaming password encryption
Version 1 byte Format version (0x01)
ChunkSize 4 bytes Chunk size in bytes (little-endian)
Salt 16 bytes Random salt for PBKDF2
BaseIV 12 bytes Base initialization vector
Chunks Variable Encrypted chunks

Header Size: 34 bytes

Keyfile-Based Streaming Format (Marker 0x12)

┌─────────────┬────────────┬──────────────┬──────────────┬─────────┐
│ Marker (1B) │ Version(1B)│ ChunkSize(4B)│ BaseIV (12B) │ Chunks  │
└─────────────┴────────────┴──────────────┴──────────────┴─────────┘
Field Size Description
Marker 1 byte 0x12 - streaming keyfile encryption
Version 1 byte Format version (0x01)
ChunkSize 4 bytes Chunk size in bytes (little-endian)
BaseIV 12 bytes Base initialization vector
Chunks Variable Encrypted chunks

Header Size: 18 bytes

Chunk Format

┌───────────────────┬─────────────────────────────────┐
│ ChunkLength (4B)  │ EncryptedData + AuthTag (16B)   │
└───────────────────┴─────────────────────────────────┘
Field Size Description
ChunkLength 4 bytes Encrypted chunk size (little-endian)
EncryptedData Variable AES-GCM encrypted chunk data
Auth Tag 16 bytes Per-chunk authentication tag

IV Derivation for Chunks

Each chunk uses a unique IV derived from the base IV:

For chunk index i (0-based):
1. Copy baseIV (12 bytes)
2. Read last 4 bytes as little-endian uint32
3. XOR with chunk index i
4. Write back as little-endian uint32

This ensures:

  • No IV reuse across chunks
  • Deterministic IV generation for each chunk index
  • Compatibility with the browser implementation (DataView getUint32/setUint32 with LE)

Keyfile Format

{
  "version": 1,
  "algorithm": "AES-256-GCM",
  "key": "<base64-encoded-32-bytes>",
  "createdAt": "2026-01-01T00:00:00.000Z"
}
Field Type Description
version int Format version (always 1)
algorithm string Algorithm identifier ("AES-256-GCM")
key string Base64-encoded 256-bit key
createdAt string ISO 8601 / RFC3339 timestamp

Key Hash Computation

hash = hex(SHA-256(base64_decode(key)))
  1. Base64-decode key to raw 32 bytes
  2. Compute SHA-256 hash
  3. Return lowercase hex string

Security Properties

Confidentiality

  • AES-256 - 256-bit keys provide 2^256 possible key combinations
  • Unique IVs - Random IVs prevent identical plaintexts from producing identical ciphertexts
  • Streaming IVs - Per-chunk IV derivation prevents IV reuse

Integrity

  • GCM Authentication - 128-bit authentication tag detects any tampering
  • Per-Chunk Authentication - Streaming encryption authenticates each chunk independently
  • Early Failure - Corrupted data detected immediately during decryption

Key Protection

  • PBKDF2 Hardening - 100,000 iterations slow brute-force attacks
  • Random Salt - Unique salt per encryption prevents rainbow table attacks
  • Cryptographic RNG - All random values from crypto/rand

Security Best Practices

Password Selection

// Good: Long, random passwords
password := "correct-horse-battery-staple-42!"

// Better: Use keyfiles for automated systems
kf, _ := filecrypto.GenerateKeyFile()

Keyfile Storage

  1. Separate Storage - Keep keyfiles separate from encrypted data
  2. Backup - Maintain secure backups of keyfiles
  3. Access Control - Set restrictive file permissions (0600)
  4. Secure Transfer - Use encrypted channels to share keyfiles

Application Security

// Always handle errors specifically
plain, err := filecrypto.Decrypt(data, opts)
if err != nil {
	if filecrypto.IsCryptoErrorCode(err, filecrypto.ErrInvalidPassword) {
		// Don't reveal whether password or data is wrong to end users
		log.Println("Decryption failed")
	}
}

// Clear sensitive data when done
password = ""
keyData = ""

Limitations

Go Runtime

  • Garbage Collection - No guaranteed secure memory clearing (GC decides when to free)
  • String Immutability - Password strings cannot be zeroed after use
  • Side Channels - Timing attacks possible in some scenarios

Not Suitable For

  • Key Management - Use dedicated HSMs or vault systems for production key storage
  • Multi-Party Encryption - No support for shared keys or threshold encryption
  • Forward Secrecy - Same key encrypts all files

Compliance Notes

This library implements cryptographic primitives following:

  • NIST SP 800-38D - AES-GCM specification
  • NIST SP 800-132 - PBKDF2 recommendations
  • OWASP Guidelines - Secure cryptographic practices

For compliance-critical applications, consult with security professionals to ensure the implementation meets your specific requirements.


Custom Profile

The Profile struct allows customizing cryptographic parameters. Zero-value fields default to browser-compatible values.

type Profile struct {
	SaltLength           int  // Default: 16
	IVLength             int  // Default: 12
	KeyLengthBytes       int  // Default: 32
	AuthTagLength        int  // Default: 16
	PBKDF2Iterations     int  // Default: 100,000
	MarkerPassword       byte // Default: 0x01
	MarkerKeyfile        byte // Default: 0x02
	MarkerPasswordStream byte // Default: 0x11
	MarkerKeyfileStream  byte // Default: 0x12
	StreamVersion        byte // Default: 0x01
	DefaultChunkSize     int  // Default: 65,536
}

Warning: Changing profile values breaks compatibility with the browser library. Only use custom profiles when you control both encryption and decryption endpoints.

There aren't any published security advisories