Encryption Details

Technical specifications of Passary's cryptography

This page provides detailed technical information about the cryptographic algorithms, parameters, and implementation details used in Passary. For a higher-level overview, see our Zero-Knowledge Architecture page.

Encryption Stack Overview

ComponentAlgorithm/StandardPurpose
Key DerivationArgon2idDerive encryption key from master password
Symmetric EncryptionAES-256-GCMEncrypt/decrypt vault data
Random Number GenerationWeb Crypto APIGenerate salts, IVs, and secure random values
StorageIndexedDBStore encrypted vault locally

Argon2id Key Derivation

Argon2id is a memory-hard key derivation function (KDF) that won the Password Hashing Competition in 2015. It's designed to resist brute-force attacks even on specialized hardware.

Parameters

memory

64 MB (65536 KB)

Amount of memory required for computation. Higher values increase resistance to GPU/ASIC attacks.

iterations

3

Number of iterations. Combined with memory parameter for tuned defense.

parallelism

1

Degree of parallelism. Set to 1 for browser compatibility.

hash length

32 bytes (256 bits)

Output length matching AES-256 key size.

salt

16 bytes (128 bits)

Cryptographically random salt, unique per vault, stored alongside encrypted data.

Why Argon2id?

  • Memory-hard: Requires significant RAM, making GPU/ASIC attacks economically infeasible
  • Hybrid approach: Argon2id combines Argon2i (data-independent) and Argon2d (data-dependent) for side-channel resistance and brute-force defense
  • Industry standard: Recommended by OWASP, used by major password managers
  • Configurable: Parameters can be tuned for security vs. performance trade-offs

Implementation

We use the argon2-browser library, a WebAssembly implementation of Argon2 that runs efficiently in modern browsers:

import { hash } from 'argon2-browser';

const result = await hash({
  pass: masterPassword,
  salt: salt,
  time: 3,           // iterations
  mem: 65536,        // 64 MB
  hashLen: 32,       // 256 bits
  parallelism: 1,
  type: argon2.Type.Argon2id
});

const encryptionKey = result.hash;

AES-256-GCM Encryption

Advanced Encryption Standard (AES) with 256-bit keys in Galois/Counter Mode (GCM) is our symmetric encryption algorithm of choice.

Specifications

Algorithm

AES-256-GCM

NIST FIPS 197 compliant, 256-bit key size

Mode

GCM (Galois/Counter Mode)

Provides both confidentiality and authenticity (AEAD - Authenticated Encryption with Associated Data)

IV/Nonce

12 bytes (96 bits)

Randomly generated for each encryption operation, stored with ciphertext

Tag Length

16 bytes (128 bits)

Authentication tag to verify data integrity

Why AES-256-GCM?

  • Military-grade: Used by US government for TOP SECRET information (NSA Suite B)
  • Authenticated encryption: GCM mode provides both encryption and integrity verification
  • Performance: Hardware-accelerated on modern CPUs via AES-NI instructions
  • Proven security: No known practical attacks against AES-256
  • Key size: 256-bit keys provide protection against quantum computing attacks (Grover's algorithm)

Implementation

We use the browser's native Web Crypto API for AES-GCM operations:

// Encryption
const iv = crypto.getRandomValues(new Uint8Array(12));
const encrypted = await crypto.subtle.encrypt(
  {
    name: 'AES-GCM',
    iv: iv,
    tagLength: 128
  },
  encryptionKey,
  vaultData
);

// Decryption
const decrypted = await crypto.subtle.decrypt(
  {
    name: 'AES-GCM',
    iv: iv,
    tagLength: 128
  },
  encryptionKey,
  ciphertext
);

Vault Data Structure

Your encrypted vault file contains the following components:

1

Argon2 Salt (16 bytes)

Random salt used for key derivation

2

AES-GCM IV/Nonce (12 bytes)

Initialization vector for encryption

3

Encrypted Vault Data (variable length)

Your passwords and vault entries in encrypted form

4

Authentication Tag (16 bytes)

GCM authentication tag for integrity verification

Note on Salt Storage

The Argon2 salt and AES IV are not secrets—they can be safely stored alongside the encrypted data. The salt ensures rainbow table attacks are ineffective, while the IV ensures semantic security (same plaintext encrypts to different ciphertext each time).

Security Analysis

Brute-Force Resistance

With AES-256, there are 2^256 possible keys (approximately 1.15 × 10^77). Even with all the world's computing power:

  • Trying 1 billion keys per second would take 3.67 × 10^59 years
  • The universe is only 1.38 × 10^10 years old
  • Practically impossible with current or foreseeable technology

Quantum Resistance

Grover's algorithm (quantum attack) reduces AES-256 security to effective 128-bit strength—still far beyond brute-force reach. Argon2id's memory-hard property also provides quantum resistance.

Side-Channel Protection

Web Crypto API implementations use constant-time operations to prevent timing attacks. Argon2id's design resists cache-timing and other side-channel attacks.

Standards Compliance

Standard/SpecificationCompliance
NIST FIPS 197 (AES)✓ Compliant
NIST SP 800-38D (GCM)✓ Compliant
RFC 9106 (Argon2)✓ Compliant
W3C Web Cryptography API✓ Used
OWASP Password Storage✓ Follows best practices

Learn More