npm package: @kitsuneislife/keyring-vcm
Description: Sistema seguro de criptografia de vídeo por chunks usando AES-256-GCM com validações robustas e verificação de integridade
Author: kitsuneislife
Latest version: 1.0.1

<div align="center">
  <img src="banner.png" alt="Keyring VCM Banner" width="100%">
</div>
<br>
<div align="center">

[![Tests](https://img.shields.io/badge/tests-passing-brightgreen.svg)](./tests)
[![TypeScript](https://img.shields.io/badge/TypeScript-5.0-blue.svg)](https://www.typescriptlang.org/)
[![Node](https://img.shields.io/badge/node-%3E%3D16.0.0-brightgreen.svg)](https://nodejs.org)

</div>

Sistema profissional de criptografia de vídeo por chunks usando **AES-256-GCM**, projetado para **segurança máxima**, **streaming eficiente** e **integridade garantida**.

## 🎯 Características

✅ **Segurança Criptográfica de Nível Militar**
- AES-256-GCM (confidencialidade + autenticação + integridade)
- HKDF para derivação de chaves isoladas por vídeo
- IV único por chunk (zero reuso)
- AAD protege contra reordenação e substituição

✅ **Streaming e Performance**
- Chunks de 512KB (configurável)
- Processamento em stream (zero carregamento em memória)
- Suporta arquivos de qualquer tamanho
- Pipeline assíncrono com Node.js Streams

✅ **Robustez e Confiabilidade**
- Verificação de integridade por chunk
- Detecção automática de corrupção
- Retry granular (por chunk)
- 100% reversível (bit-by-bit equality)

✅ **Flexibilidade**
- Binário ou texto (base64/hex)
- API simples e intuitiva
- Uso em memória ou filesystem
- TypeScript-friendly

---

## 📦 Instalação

```bash
npm install @kitsuneislife/keyring-vcm
```

**Requisitos:**
- Node.js >= 18.0.0 (usa crypto nativo)

---

## 🚀 Uso Rápido

### Exemplo Básico

```javascript
import {
  generateMasterKey,
  encryptFile,
  decryptFile
} from '@kitsuneislife/keyring-vcm';

// 1. Gera master key (faça UMA VEZ e guarde com segurança)
const masterKey = generateMasterKey();

// 2. Encripta
await encryptFile({
  inputPath: 'video.mp4',
  outputPath: 'video.encrypted',
  masterKey,
  videoId: 'user-123-video-001'
});

// 3. Decripta
await decryptFile({
  inputPath: 'video.encrypted',
  outputPath: 'video-restored.mp4',
  masterKey,
  videoId: 'user-123-video-001'
});
```

### Em Memória (Buffer)

```javascript
import { encryptBuffer, decryptBuffer, generateMasterKey } from '@kitsuneislife/keyring-vcm';

const masterKey = generateMasterKey();
const videoData = Buffer.from('...');

// Encripta
const chunks = await encryptBuffer({
  data: videoData,
  masterKey,
  videoId: 'video-001'
});

// Decripta
const restored = await decryptBuffer({
  chunks,
  masterKey,
  videoId: 'video-001'
});
```

---

## 🔑 Gestão de Chaves

### Master Key (Única para toda aplicação)

```javascript
import { generateMasterKey, exportMasterKey, importMasterKey } from '@kitsuneislife/keyring-vcm';

// Gera (faça uma vez)
const masterKey = generateMasterKey();

// Exporta para armazenamento
const hexKey = exportMasterKey(masterKey);
// Salve em: ENV var, AWS KMS, HashiCorp Vault, etc.

// Importa quando necessário
const recovered = importMasterKey(hexKey);
```

### Chaves por Vídeo (Automático)

O sistema usa **HKDF** para derivar uma chave única por vídeo:

```
video_key = HKDF(master_key, video_id)
```

**Vantagens:**
- Uma master key protege infinitos vídeos
- Cada vídeo tem isolamento criptográfico
- Rotação simples (troca master key)
- Zero risco de reuso de chave

---

## 📚 API Completa

### `generateMasterKey()`
Gera uma master key de 32 bytes (256 bits).

**Retorna:** `Buffer`

```javascript
const masterKey = generateMasterKey();
```

---

### `encryptFile(options)`
Encripta um arquivo usando streaming.

**Parâmetros:**
```javascript
{
  inputPath: string,      // Caminho do arquivo original
  outputPath: string,     // Caminho do arquivo criptografado
  masterKey: Buffer,      // Master key (32 bytes)
  videoId: string,        // ID único do vídeo
  encoding?: string,      // 'binary' (padrão), 'base64', 'hex'
  chunkSize?: number      // Tamanho do chunk (padrão: 512KB)
}
```

**Retorna:** `Promise<{ totalChunks, bytesProcessed }>`

**Exemplo:**
```javascript
const stats = await encryptFile({
  inputPath: 'movie.mp4',
  outputPath: 'movie.enc',
  masterKey,
  videoId: 'movie-2024-001',
  encoding: 'base64'  // Texto ao invés de binário
});

console.log(`Processados ${stats.totalChunks} chunks`);
```

---

### `decryptFile(options)`
Descriptografa um arquivo.

**Parâmetros:**
```javascript
{
  inputPath: string,      // Arquivo criptografado
  outputPath: string,     // Arquivo restaurado
  masterKey: Buffer,      // Mesma master key
  videoId: string,        // Mesmo videoId
  encoding?: string       // Mesmo encoding usado na criptografia
}
```

**Retorna:** `Promise<{ chunksProcessed, bytesProcessed }>`

---

### `encryptBuffer(options)`
Encripta dados em memória.

**Parâmetros:**
```javascript
{
  data: Buffer,          // Dados a criptografar
  masterKey: Buffer,     // Master key
  videoId: string,       // ID do vídeo
  chunkSize?: number     // Tamanho do chunk
}
```

**Retorna:** `Promise<Buffer[]>` - Array de chunks criptografados

---

### `decryptBuffer(options)`
Descriptografa dados em memória.

**Parâmetros:**
```javascript
{
  chunks: Buffer[],      // Chunks criptografados
  masterKey: Buffer,     // Master key
  videoId: string        // ID do vídeo
}
```

**Retorna:** `Promise<Buffer>` - Dados restaurados

---

## 🏗️ Arquitetura

### Formato do Chunk Criptografado

Cada chunk tem esta estrutura binária compacta:

```
┌─────────────┬─────────┬──────────┬──────────────┐
│ chunk_index │   IV    │   TAG    │  ciphertext  │
│   4 bytes   │ 12 bytes│ 16 bytes │   N bytes    │
└─────────────┴─────────┴──────────┴──────────────┘
       ↓            ↓         ↓           ↓
    uint32BE    random    auth tag    dados
```

**Overhead:** 32 bytes por chunk (~0.006% para chunks de 512KB)

### Fluxo de Criptografia

```
[Video File]
     ↓
[Chunk 512KB] → [Derive Key] → [Random IV] → [AES-256-GCM] → [Encrypted Chunk]
     ↓                              ↓              ↓                ↓
[Chunk 512KB]                   [AAD]         [Auth Tag]      [Storage]
     ↓
[Last Chunk]
```

### AAD (Additional Authenticated Data)

Cada chunk é autenticado com:

```
AAD = SHA256(video_id || chunk_index)
```

Isso protege contra:
- ❌ Reordenação de chunks
- ❌ Substituição entre vídeos
- ❌ Ataques de replay
- ❌ Modificação silenciosa

---

## 🧪 Testes

Execute os testes completos:

```bash
npm test
```

**Cobertura:**
- ✅ Testes unitários (HKDF, AAD, Crypto)
- ✅ Testes de integração (arquivos, buffers)
- ✅ Testes de segurança (corrupção, chaves erradas)
- ✅ Testes de streaming

---

## 📖 Exemplos

### 1. Uso Básico
```bash
node examples/basic-usage.js
```

### 2. Buffer em Memória
```bash
node examples/buffer-usage.js
```

### 3. Streaming com Progresso
```bash
node examples/streaming-usage.js
```

### 4. Múltiplos Vídeos
```bash
node examples/multi-video.js
```

---

## 🛡️ Segurança

### Garantias Criptográficas

✅ **Confidencialidade:** AES-256-GCM (padrão NIST)  
✅ **Integridade:** Tag de autenticação por chunk  
✅ **Autenticidade:** AAD vincula chunk ao contexto  
✅ **Unicidade:** IV aleatório nunca reutilizado  
✅ **Isolamento:** HKDF separa chaves por vídeo  

### Proteções Implementadas

- **Contra modificação:** Tag GCM detecta qualquer alteração
- **Contra reordenação:** AAD inclui índice do chunk
- **Contra substituição:** AAD inclui videoId
- **Contra replay:** Combinação de IV + AAD
- **Contra corrupção:** Falha imediata e detectável

### Não Protege Contra (fora do escopo)

❌ Vazamento de chave (responsabilidade do usuário)  
❌ Ataques de canal lateral (timing, power)  
❌ Ocultação de tamanho do arquivo  
❌ DRM ou proteção contra cópia  

---

## ⚡ Performance

### Benchmarks (Node.js 20, CPU típico)

| Tamanho   | Encriptação | Decriptação | Throughput |
|-----------|-------------|-------------|------------|
| 10 MB     | ~50 ms      | ~45 ms      | ~200 MB/s  |
| 100 MB    | ~450 ms     | ~420 ms     | ~220 MB/s  |
| 1 GB      | ~4.5 s      | ~4.2 s      | ~230 MB/s  |

**Notas:**
- Usa crypto nativo do Node.js (C++)
- Streaming evita uso de memória
- Gargalo é I/O, não CPU

---

## 🔧 Configuração Avançada

### Chunk Size Customizado

```javascript
await encryptFile({
  inputPath: 'video.mp4',
  outputPath: 'video.enc',
  masterKey,
  videoId: 'video-001',
  chunkSize: 1024 * 1024  // 1MB chunks
});
```

**Trade-offs:**
- Chunks menores: mais overhead, melhor granularidade
- Chunks maiores: menos overhead, menos granularidade

**Recomendado:** 512KB (padrão)

### Encoding para Texto

```javascript
// Base64 (padrão texto)
await encryptFile({
  inputPath: 'video.mp4',
  outputPath: 'video.txt',
  masterKey,
  videoId: 'video-001',
  encoding: 'base64'
});

// Hex
await encryptFile({
  inputPath: 'video.mp4',
  outputPath: 'video.hex',
  masterKey,
  videoId: 'video-001',
  encoding: 'hex'
});
```

---

## 🔄 Casos de Uso

### 1. Upload Seguro para Cloud

```javascript
// Cliente
const chunks = await encryptBuffer({
  data: videoBuffer,
  masterKey: clientKey,
  videoId: uploadId
});

// Upload chunks em paralelo
await Promise.all(chunks.map((chunk, i) => 
  uploadToS3(`${uploadId}/chunk-${i}`, chunk)
));
```

### 2. Streaming de Vídeo Protegido

```javascript
import { EncryptionStream, ChunkSerializationStream } from '@kitsuneislife/keyring-vcm';

const encStream = new EncryptionStream(videoKey, videoId);
const serStream = new ChunkSerializationStream();

videoSource
  .pipe(encStream)
  .pipe(serStream)
  .pipe(httpResponse);
```

### 3. Backup Criptografado

```javascript
// Encripta antes do backup
await encryptFile({
  inputPath: 'important-video.mp4',
  outputPath: 'backup/video.enc',
  masterKey,
  videoId: 'backup-2024-001'
});

// Restaura quando necessário
await decryptFile({
  inputPath: 'backup/video.enc',
  outputPath: 'restored.mp4',
  masterKey,
  videoId: 'backup-2024-001'
});
```

---

## 🤝 Contribuindo

Contribuições são bem-vindas! 

**Áreas de interesse:**
- Otimizações de performance
- Suporte a WebCrypto (browser)
- Implementação de Base85
- Documentação adicional

---

## 📄 Licença

MIT License - veja [LICENSE](LICENSE) para detalhes.

---

## 🙏 Agradecimentos

Este projeto implementa **best practices** recomendadas por:
- NIST (National Institute of Standards and Technology)
- OWASP (Cryptographic Storage Cheat Sheet)
- Node.js Crypto Module Documentation

---

## ⚠️ Aviso de Segurança

**IMPORTANTE:**

1. **Guarde a master key com segurança absoluta**
   - Use variáveis de ambiente
   - KMS (AWS, GCP, Azure)
   - Vaults (HashiCorp, etc.)
   - **NUNCA comite no código**

2. **Use HTTPS/TLS para transmissão**
   - Este módulo protege dados em repouso
   - Use TLS para dados em trânsito

3. **Validação de entrada**
   - Sempre valide `videoId` antes de usar
   - Evite collision de IDs

4. **Rotação de chaves**
   - Considere rotação periódica da master key
   - Re-encripte vídeos antigos quando necessário

---

## 📞 Suporte

Para questões de segurança: **[seu-email-de-segurança]**  
Para bugs/features: Abra uma issue no GitHub

---

**Desenvolvido com ❤️ e foco em segurança máxima.**