Passkeys e WebAuthn: O Futuro da Autenticacao Chegou
Ola HaWkers, voce provavelmente ja viu a opcao "Entrar com Passkey" aparecendo em mais e mais sites. Esta semana, o Telegram anunciou suporte a passkeys, seguindo uma tendencia que esta transformando como nos autenticamos na web.
Voce ainda depende de senhas tradicionais? Vamos entender por que passkeys sao consideradas o futuro da autenticacao e como implementa-las em suas aplicacoes.
O Que Sao Passkeys e WebAuthn
Passkeys e WebAuthn nao sao tecnologias concorrentes - sao partes de um sistema que trabalha junto para permitir login sem senha de forma segura.
WebAuthn (Web Authentication)
WebAuthn e uma API padrao desenvolvida pela FIDO Alliance e W3C que permite logins sem senhas tradicionais.
Caracteristicas principais:
- Baseado em criptografia de chave publica
- Padrao do W3C desde 2019
- Suportado por todos os navegadores modernos
- Componente central do projeto FIDO2
Passkeys
Passkeys sao credenciais de autenticacao FIDO que permitem login usando o mesmo processo de desbloqueio do dispositivo.
Como funcionam:
- Usam biometria, PIN ou padrao do dispositivo
- Sincronizados entre dispositivos via cloud
- Nao requerem memorizar senhas
- Resistentes a phishing por design
Por Que Passkeys Sao Mais Seguros
Senhas tradicionais tem problemas fundamentais de seguranca que passkeys resolvem por design.
Problemas das Senhas
Vulnerabilidades comuns:
| Problema | Senhas | Passkeys |
|---|---|---|
| Reutilizacao | Comum | Impossivel |
| Phishing | Vulneravel | Imune |
| Vazamento de banco | Dados expostos | Apenas chave publica |
| Forca bruta | Possivel | Impossivel |
| Keyloggers | Vulneravel | Imune |
Como Passkeys Protegem
1. Vinculadas ao dominio:
Uma passkey criada para seubanco.com nao pode ser usada em seubanco.fake.com, mesmo que o usuario seja enganado.
2. Sem segredo compartilhado:
O servidor armazena apenas a chave publica, que e inutil sem a chave privada que nunca sai do dispositivo.
3. Unicas por servico:
Cada passkey e um par de chaves unico, entao vazamento de um servico nao afeta outros.
Como Funciona Tecnicamente
Vamos entender o fluxo de registro e autenticacao com WebAuthn.
Fluxo de Registro
// 1. Servidor gera challenge e opcoes
const publicKeyCredentialCreationOptions = {
challenge: new Uint8Array(32), // Challenge aleatorio do servidor
rp: {
name: "Minha Aplicacao",
id: "meusite.com"
},
user: {
id: new Uint8Array(16), // ID unico do usuario
name: "usuario@email.com",
displayName: "Nome do Usuario"
},
pubKeyCredParams: [
{ alg: -7, type: "public-key" }, // ES256
{ alg: -257, type: "public-key" } // RS256
],
authenticatorSelection: {
authenticatorAttachment: "platform",
residentKey: "required",
userVerification: "required"
},
timeout: 60000
};
// 2. Navegador solicita criacao de credencial
const credential = await navigator.credentials.create({
publicKey: publicKeyCredentialCreationOptions
});
// 3. Enviar chave publica para o servidor armazenar
await fetch('/api/auth/register', {
method: 'POST',
body: JSON.stringify({
id: credential.id,
rawId: btoa(String.fromCharCode(...new Uint8Array(credential.rawId))),
response: {
clientDataJSON: btoa(String.fromCharCode(
...new Uint8Array(credential.response.clientDataJSON)
)),
attestationObject: btoa(String.fromCharCode(
...new Uint8Array(credential.response.attestationObject)
))
}
})
});
Fluxo de Autenticacao
// 1. Servidor envia challenge
const publicKeyCredentialRequestOptions = {
challenge: new Uint8Array(32), // Challenge novo do servidor
rpId: "meusite.com",
allowCredentials: [], // Vazio para passkeys descobriveis
userVerification: "required",
timeout: 60000
};
// 2. Navegador solicita autenticacao
const assertion = await navigator.credentials.get({
publicKey: publicKeyCredentialRequestOptions
});
// 3. Enviar assinatura para verificacao no servidor
const response = await fetch('/api/auth/login', {
method: 'POST',
body: JSON.stringify({
id: assertion.id,
rawId: btoa(String.fromCharCode(...new Uint8Array(assertion.rawId))),
response: {
clientDataJSON: btoa(String.fromCharCode(
...new Uint8Array(assertion.response.clientDataJSON)
)),
authenticatorData: btoa(String.fromCharCode(
...new Uint8Array(assertion.response.authenticatorData)
)),
signature: btoa(String.fromCharCode(
...new Uint8Array(assertion.response.signature)
))
}
})
});Implementacao Pratica
Para facilitar a implementacao, existem bibliotecas que abstraem a complexidade.
SimpleWebAuthn (Recomendado)
// Frontend - @simplewebauthn/browser
import {
startRegistration,
startAuthentication
} from '@simplewebauthn/browser';
// Registro
const registrationOptions = await fetch('/api/webauthn/register-options')
.then(res => res.json());
const registration = await startRegistration(registrationOptions);
await fetch('/api/webauthn/register', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(registration)
});
// Login
const authOptions = await fetch('/api/webauthn/auth-options')
.then(res => res.json());
const authentication = await startAuthentication(authOptions);
await fetch('/api/webauthn/authenticate', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(authentication)
});
Backend com Node.js
// Backend - @simplewebauthn/server
import {
generateRegistrationOptions,
verifyRegistrationResponse,
generateAuthenticationOptions,
verifyAuthenticationResponse
} from '@simplewebauthn/server';
// Gerar opcoes de registro
app.get('/api/webauthn/register-options', async (req, res) => {
const options = await generateRegistrationOptions({
rpName: 'Minha Aplicacao',
rpID: 'meusite.com',
userID: user.id,
userName: user.email,
attestationType: 'none',
authenticatorSelection: {
residentKey: 'required',
userVerification: 'required'
}
});
// Salvar challenge na sessao
req.session.challenge = options.challenge;
res.json(options);
});
// Verificar registro
app.post('/api/webauthn/register', async (req, res) => {
const verification = await verifyRegistrationResponse({
response: req.body,
expectedChallenge: req.session.challenge,
expectedOrigin: 'https://meusite.com',
expectedRPID: 'meusite.com'
});
if (verification.verified) {
// Salvar credencial no banco de dados
await saveCredential(user.id, verification.registrationInfo);
res.json({ success: true });
}
});Atualizacoes de 2025
O ecossistema de passkeys continua evoluindo com melhorias significativas.
WebAuthn Level 3
A especificacao WebAuthn Level 3 foi publicada como Working Draft em janeiro de 2025, trazendo:
- APIs aprimoradas para criacao e uso de passkeys
- Novos recursos de seguranca
- Melhor suporte cross-device
Diretrizes NIST
O NIST finalizara as Digital Identity Guidelines (SP 800-63-4) em julho de 2025:
- Passkeys reconhecidas como "syncable authenticators"
- Podem atingir Authenticator Assurance Level 2 (AAL2)
- MFA resistente a phishing exigido para agencias federais dos EUA
Portabilidade de Passkeys
A FIDO Alliance esta desenvolvendo novos protocolos:
- CXP (Credential Exchange Protocol) - Transferencia segura entre provedores
- CXF (Credential Exchange Format) - Formato padrao de troca
Plataformas com Suporte
Passkeys ja sao suportadas pelas principais plataformas.
Sincronizacao por Provedor
| Provedor | Sincronizacao | Plataformas |
|---|---|---|
| Apple | iCloud Keychain | iOS, macOS |
| Google Password Manager | Android, Chrome | |
| Microsoft | Windows Hello | Windows 10/11 |
| 1Password | Aplicativo | Todas |
| Dashlane | Aplicativo | Todas |
Adocao por Servicos
Servicos populares com suporte a passkeys:
- Microsoft
- Apple
- Amazon
- GitHub
- PayPal
- eBay
- Nintendo
- Telegram (novembro 2025)
Consideracoes de Implementacao
Ao adicionar passkeys a sua aplicacao, considere estes pontos.
Fallback Necessario
Nem todos os dispositivos suportam passkeys. Mantenha opcoes alternativas:
// Verificar suporte do navegador
const supportsWebAuthn = () => {
return window.PublicKeyCredential !== undefined &&
typeof window.PublicKeyCredential === 'function';
};
// Verificar suporte a passkeys condicionais
const supportsConditionalUI = async () => {
if (!supportsWebAuthn()) return false;
return await PublicKeyCredential
.isConditionalMediationAvailable?.() ?? false;
};UX Considerations
- Oferecer passkeys como opcao, nao obrigatorio
- Explicar beneficios para usuarios
- Permitir registro de multiplas passkeys
- Manter metodo de recuperacao
Conclusao
Passkeys representam a maior evolucao em autenticacao web desde a popularizacao de senhas. Com suporte amplo de navegadores e sistemas operacionais, resistencia intrinseca a phishing e experiencia de usuario superior, e o momento certo para comecar a implementar.
Para desenvolvedores, bibliotecas como SimpleWebAuthn tornam a implementacao acessivel. Para usuarios, a experiencia e mais simples e segura que senhas tradicionais.
Se voce quer aprofundar seus conhecimentos em seguranca web, recomendo que de uma olhada em outro artigo: GitHub Actions Muda Precos em 2026 onde voce vai descobrir como proteger seus pipelines de CI/CD.
Bora pra cima! 🦅
💻 Domine JavaScript de Verdade
O conhecimento que voce adquiriu neste artigo e so o comeco. Ha tecnicas, padroes e praticas que transformam desenvolvedores iniciantes em profissionais requisitados.
Invista no Seu Futuro
Preparei um material completo para voce dominar JavaScript:
Formas de pagamento:
- 1x de R$9,90 sem juros
- ou R$9,90 a vista

