Protocolo de Criptografia

O CriptEnv utiliza uma cadeia de derivação de chaves em múltiplas camadas para garantir que cada ambiente tenha uma chave criptográfica única e isolada. Todo o processo acontece no navegador do usuário — o servidor nunca tem acesso às chaves ou aos dados em texto claro.

Fluxo de Derivação de Chaves

O processo completo de derivação segue estas etapas:

text
┌─────────────────────────────────────────────────────────┐
│  1. SENHA MESTRA (input do usuário)                     │
│     Exemplo: "minha-senha-segura-123"                   │
└──────────────────────┬──────────────────────────────────┘
                       │
                       ▼
┌─────────────────────────────────────────────────────────┐
│  2. PBKDF2-HMAC-SHA256                                  │
│     Iterações: 100.000                                  │
│     Salt: 32 bytes aleatórios (gerado no registro)      │
│     Output: 256-bit Master Key                          │
└──────────────────────┬──────────────────────────────────┘
                       │
                       ▼
┌─────────────────────────────────────────────────────────┐
│  3. HKDF-SHA256 (por ambiente)                          │
│     IKM: Master Key                                     │
│     Salt: environment_id (UUID do ambiente)             │
│     Info: "criptenv-vault-v1"                           │
│     Output: 256-bit Environment Key                     │
└──────────────────────┬──────────────────────────────────┘
                       │
                       ▼
┌─────────────────────────────────────────────────────────┐
│  4. AES-256-GCM                                         │
│     Key: 256-bit Environment Key                        │
│     IV: 12 bytes aleatórios (por operação)              │
│     Auth Tag: 128 bits                                  │
│     Output: ciphertext + IV + auth_tag                  │
└─────────────────────────────────────────────────────────┘

Parâmetros Criptográficos

PBKDF2 (Derivação da Chave Mestra)

ParâmetroTipoDescrição
AlgoritmostringHMAC-SHA256 — Função pseudo-aleatória baseada em hash
Iteraçõesnumber100.000 iterações — proteção contra força bruta
Tamanho do Saltnumber32 bytes (256 bits) — gerado aleatoriamente no momento do registro
Tamanho da Chavenumber32 bytes (256 bits) — chave mestra de saída

HKDF (Derivação por Ambiente)

ParâmetroTipoDescrição
AlgoritmostringSHA-256 — Função de hash subjacente
IKM (Input Key Material)stringChave mestra de 256 bits derivada do PBKDF2
SaltstringID do ambiente (UUID) — garante chave única por ambiente
Infostring"criptenv-vault-v1" — contexto do domíneo de aplicação
Tamanho da Chavenumber32 bytes (256 bits) — chave do ambiente de saída

AES-256-GCM (Criptografia dos Dados)

ParâmetroTipoDescrição
AlgoritmostringAES-256-GCM — Criptografia autenticada com Galois/Counter Mode
Tamanho da Chavenumber32 bytes (256 bits) — chave do ambiente derivada via HKDF
IV (Nonce)number12 bytes (96 bits) — gerado aleatoriamente para cada operação de criptografia
Auth Tagnumber16 bytes (128 bits) — tag de autenticação para verificação de integridade

Info

O IV (vetor de inicialização) é gerado aleatoriamente para cada operação de criptografia. Nunca reutilize um IV com a mesma chave — isso comprometeria a segurança do GCM.

Derivação do Vault Proof

Além da chave de criptografia, o CriptEnv deriva uma chave de prova separada usada para autorização na API. Isso permite autenticar o usuário sem revelar a chave mestra ou a chave de criptografia.

text
┌─────────────────────────────────────────────────────────┐
│  PBKDF2-HMAC-SHA256                                     │
│     Password: Senha Mestra                              │
│     Salt: "proof_salt" (constante do sistema)           │
│     Iterações: 100.000                                  │
│     Output: Vault Proof (256-bit)                       │
└─────────────────────────────────────────────────────────┘

O Vault Proof é enviado ao servidor para verificação.
O servidor armazena apenas o hash do proof para comparação.
A chave de criptografia real nunca é transmitida.

Cofre Local vs. Nuvem

O cofre local é armazenado em SQLite no diretório do usuário:

text
Localização: ~/.criptenv/vault.db

Estrutura do banco de dados:
├── sessions     → Sessões autenticadas (criptografadas)
├── environments → Ambientes com chaves derivadas
└── secrets      → Variáveis de ambiente (criptografadas)

Recursos de segurança:
• Banco de dados com permissões restritivas (0600)
• Sessões com expiração automática
• Chaves de sessão não persistidas em disco
• Cleanup automático de sessões expiradas

Info

O cofre local permite uso offline completo. Todos os segredos necessários para descriptografar seus ambientes estão disponíveis localmente após a autenticação inicial.

Implementação

Exemplo simplificado do fluxo de criptografia usando a Web Crypto API:

typescript
// 1. Derivação da chave mestra via PBKDF2
const masterKey = await crypto.subtle.importKey(
  'raw',
  new TextEncoder().encode(password),
  'PBKDF2',
  false,
  ['deriveBits', 'deriveKey']
);

const derivedKey = await crypto.subtle.deriveKey(
  {
    name: 'PBKDF2',
    salt: salt,           // 32 bytes aleatórios
    iterations: 100_000,
    hash: 'SHA-256',
  },
  masterKey,
  { name: 'HKDF' },
  true,
  ['deriveKey']
);

// 2. Derivação da chave do ambiente via HKDF
const envKey = await crypto.subtle.deriveKey(
  {
    name: 'HKDF',
    salt: new TextEncoder().encode(envId),  // UUID do ambiente
    info: new TextEncoder().encode('criptenv-vault-v1'),
    hash: 'SHA-256',
  },
  derivedKey,
  { name: 'AES-GCM', length: 256 },
  false,
  ['encrypt', 'decrypt']
);

// 3. Criptografia com AES-256-GCM
const iv = crypto.getRandomValues(new Uint8Array(12)); // 96 bits
const encrypted = await crypto.subtle.encrypt(
  { name: 'AES-GCM', iv, tagLength: 128 },
  envKey,
  plaintext
);

// Resultado: ciphertext + IV (12 bytes) + auth_tag (16 bytes)