Aula 11 – Criptografia na Prática com JavaScript 💻
O navegador também precisa cifrar dados — de senhas locais a comunicação ponta a ponta. Nesta aula vamos usar a Web Crypto API, nativa de todo navegador moderno e do Node.js.
📦 A Web Crypto API
Diferente do Python, o JavaScript não precisa instalar biblioteca nenhuma para operações criptográficas básicas — a crypto.subtle já vem embutida no navegador e no Node.js (via require('crypto').webcrypto).
Por que 'subtle'?
O nome é uma referência proposital: usar essa API de forma insegura é fácil e as consequências são "sutis" (subtle) — o nome é um lembrete para usar com cuidado e seguir as boas práticas.
#️⃣ Hash com crypto.subtle.digest
async function calcularHash(texto) {
const encoder = new TextEncoder();
const dados = encoder.encode(texto);
const hashBuffer = await crypto.subtle.digest("SHA-256", dados);
const hashArray = Array.from(new Uint8Array(hashBuffer));
return hashArray.map(b => b.toString(16).padStart(2, "0")).join("");
}
calcularHash("senha123").then(hash => console.log(hash));
// ef92b778bafe771e89245b89ecbc08a44a4e166c06659911881f383d4473e94
🔐 Criptografia Simétrica (AES-GCM) no Navegador
async function gerarChaveAES() {
return await crypto.subtle.generateKey(
{ name: "AES-GCM", length: 256 },
true,
["encrypt", "decrypt"]
);
}
async function cifrar(chave, texto) {
const iv = crypto.getRandomValues(new Uint8Array(12)); // IV aleatorio (Aula 04)
const encoder = new TextEncoder();
const cifrado = await crypto.subtle.encrypt(
{ name: "AES-GCM", iv },
chave,
encoder.encode(texto)
);
return { cifrado, iv };
}
graph LR
A["Texto Claro"] --> B["generateKey AES-GCM 256"]
B --> C["encrypt() com IV aleatorio"]
C --> D["ArrayBuffer cifrado"]
D --> E["decrypt() com a mesma chave + IV"]
E --> A Sempre gere um IV novo
Assim como vimos na Aula 04, reutilizar o mesmo IV com a mesma chave em AES-GCM compromete completamente a segurança da cifragem.
💻 Testando no Console do Navegador
📝 Exercícios de Fixação
- Básico: Por que a Web Crypto API não precisa de instalação, diferente da biblioteca Python da Aula 10?
- Básico: Escreva uma função que calcula o hash SHA-256 de uma senha digitada em um formulário HTML.
- Intermediário: Por que o IV é gerado com
crypto.getRandomValues()e não comMath.random()? - Intermediário: Complete o exemplo de AES-GCM com uma função
decifrar()que reverte o processo decifrar(). - Desafio: Pesquise a diferença entre
crypto.getRandomValues()(criptograficamente seguro) eMath.random()(não seguro) — por que isso importa em segurança?
🚀 Mini-Projeto: Formulário com Hash no Cliente
Objetivo: Criar uma página HTML simples que calcula o hash SHA-256 de um texto digitado, em tempo real.
- Crie um
inputde texto e uma área para mostrar o resultado. - A cada tecla digitada, calcule o hash SHA-256 do conteúdo atual usando
crypto.subtle.digest. - Exiba o hash resultante na tela, atualizado em tempo real.
- Bônus: adicione um botão para copiar o hash para a área de transferência.