Voltar para o Blog

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 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:

  • Google
  • 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

📖 Ver Conteudo Completo

Comentários (0)

Esse artigo ainda não possui comentários 😢. Seja o primeiro! 🚀🦅

Adicionar comentário