Resumo executivo
| Por que fizemos isso | A recuperação de conta deve ser rápida, legível e tranquila sem se tornar permissiva |
| Fator salvo | Recovery Code: XXXXXX-XXXXXX-CC, onde 12 caracteres são secretos e 2 são checksum |
| Fator email | Verification Code: XXXXCC, onde 4 caracteres são secretos e 2 são checksum |
| Alfabeto | ABCDEFGHJKLMNPQRTUWXYZ346789, escolhido para evitar caracteres visualmente confusos |
| Limites do servidor | Janela de código por email de 10 minutos, uso único, limites de tentativas, cooldown de reenvio, TTL de transação e telemetria de abuso |
| Limite de segurança | O código por email prova acesso à caixa de entrada. O Recovery Code prova posse do segredo salvo da conta. Nenhum dos dois basta sozinho para recuperação protegida. |
O problema que estávamos resolvendo
Recuperação não é um login normal. As pessoas chegam a ela quando algo já deu errado: um dispositivo perdido, uma passkey ausente, um telefone novo ou um prazo. Um desenho de recuperação pode ser criptograficamente sólido e ainda falhar para usuários se o código for longo demais, difícil de ler, difícil de copiar ou fácil de digitar errado.
O objetivo não era tornar a recuperação casual. O objetivo era tornar o caminho honesto menos doloroso mantendo o servidor rigoroso. Isso significou reduzir erros de transcrição, manter todos os campos importantes em uma tela, aceitar colagem de forma tolerante e validar erros óbvios antes que o usuário espere a resposta do servidor.
Os novos códigos
Ambos os códigos usam o mesmo alfabeto de acessibilidade da PayCal:
ABCDEFGHJKLMNPQRTUWXYZ346789
Excluímos intencionalmente caracteres que costumam ser confundidos ao ler, copiar, imprimir ou digitar. As entradas são normalizadas para maiúsculas e com remoção de espaços e hífens, para que usuários possam colar códigos agrupados ou não agrupados.
| Código | Formato exibido | Caracteres secretos | Caracteres checksum |
|---|---|---|---|
| Recovery Code | XXXXXX-XXXXXX-CC |
12 | 2 |
| Verification Code | XXXXCC |
4 | 2 |
O checksum não é secreto e não adiciona entropia de segurança. Ele existe para detectar erros honestos. Se os dois últimos caracteres não combinarem com a parte secreta, o navegador pode dizer imediatamente: “Check the last two characters,” antes que o usuário gaste uma tentativa no servidor.
A matemática
O Recovery Code tem 12 caracteres secretos escolhidos entre 28 símbolos possíveis. Isso dá:
28^12 = 232,218,265,089,212,416 possibilities
log2(28^12) ~= 57.7 bits
O Verification Code por email tem 4 caracteres secretos:
28^4 = 614,656 possibilities
log2(28^4) ~= 19.2 bits
Quando os dois fatores são considerados juntos, o espaço secreto de busca é:
28^16 = 142,734,349,946,674,946,768,896 possibilities
log2(28^16) ~= 76.9 bits
Um palpite aleatório contra o Recovery Code salvo é cerca de 1 em 232 quadrilhões. Um palpite aleatório contra os dois fatores juntos é cerca de 1 em 142 sextilhões. Com cinco palpites combinados, a chance ainda é cerca de 3,5 x 10^-23, ou aproximadamente 1 em 28,5 sextilhões.
Por que força bruta online demora tanto
A expressão importante é recuperação online. Atacantes não conseguem enviar palpites ilimitados pela PayCal tão rápido quanto o hardware calcula. O servidor controla o ritmo, conta falhas, expira códigos, registra telemetria de abuso e exige que o estado da transação esteja alinhado.
Com os padrões conservadores atuais, a recuperação é limitada por controles como:
- Verification Codes por email expiram após 10 minutos;
- Verification Codes por email são de uso único;
- endpoints de verificação e proof têm limite de tentativas;
- inícios de recuperação são limitados por dia;
- reenvios são limitados por hora e têm cooldown;
- falhas de checksum vistas pelo servidor contam para telemetria de abuso e política de tentativas;
- transações de recuperação e janelas bootstrap expiram;
- o servidor, não o navegador, permanece autoritativo.
Com cinco palpites por hora, tentar metade do espaço do Recovery Code levaria cerca de 2,65 trilhões de anos. Tentar metade do espaço combinado de Recovery Code mais código por email no mesmo ritmo online levaria cerca de 1,63 quintilhão de anos. Esse é o “tempo realmente, realmente longo” que queremos dizer: não porque o usuário precise carregar um código enorme, mas porque a recuperação online tem múltiplos fatores e o servidor não deixa palpites correrem livremente.
A janela de 10 minutos
O código por email é intencionalmente curto porque não deve proteger a conta sozinho. Ele tem limite de tempo, é entregue à caixa de entrada do usuário, tem limite de tentativas e é consumido no sucesso.
Com 614.656 possíveis segredos de código por email, cinco palpites dentro de uma janela de 10 minutos dão no máximo 0,000813% de chance de acertar o código por acaso, ou cerca de 1 em 122.931. Isso ainda não completaria a recuperação protegida, porque o Recovery Code salvo e o recovery proof também precisam passar.
O que mudou na experiência do usuário
Reduzimos a tela de recuperação a um formulário centralizado. O usuário vê o campo de email, o campo Verification Code, o campo Recovery Code e uma ação primária: Verify and continue.
- O usuário pode colar o Recovery Code salvo enquanto espera pelo email.
- Espaços e hífens são aceitos e normalizados.
- Recovery Codes são autoformatados como
XXXXXX-XXXXXX-CC. - Verification Codes são autoformatados como
XXXXCC. - Caracteres inválidos do alfabeto mostram uma mensagem clara em linha.
- Falhas de checksum são capturadas localmente antes da requisição ao servidor.
- Quando os dois formatos parecem corretos, o formulário mostra “Checking...” e envia automaticamente após um curto debounce.
- O botão Verify and continue permanece disponível como fallback.
O resultado é mais rápido para o usuário normal: menos etapas, menos surpresas, menos estado oculto e menos punição por copiar um código com espaços ou hífens.
O que mudou no modelo de segurança
O redesenho também reforçou vários limites de recuperação:
- Recovery Codes brutos não são enviados por email. Eles são exibidos uma vez quando criados e devem ser salvos pelo usuário.
- A PayCal armazena material recovery-wrapped e estado verificador, nunca o Recovery Code bruto.
- Magic links não conseguem tornar uma conta protegida existente pronta para passkey por si só.
- Bootstrap somente por email é permitido apenas para configuração da primeira passkey quando não há material criptográfico protegido existente nem passkey existente.
- Completar a recuperação exige que o ID de credencial passkey registrado na transação de recuperação corresponda à requisição de conclusão.
- Passkeys antigas são revogadas após recuperação de conta bem-sucedida para que a nova passkey se torne a credencial confiável.
O que isso não significa
Isso não é uma afirmação de que um código legível de 12 caracteres é um segredo offline de 256 bits. A recuperação de conta da PayCal é um fluxo online, mediado pelo servidor, de dois fatores. O Recovery Code é um fator; acesso à caixa de entrada e estado da transação são outro; registro de passkey é a etapa final vinculada ao dispositivo.
Essa distinção importa. Tornamos o código legível porque as pessoas precisam salvá-lo e digitá-lo corretamente. Mantivemos o servidor rigoroso porque recuperação legível não deve significar recuperação fraca.
A regra que agora aplicamos
O código por email prova acesso à caixa de entrada.
O Recovery Code prova posse do segredo salvo da conta.
Nenhum deles basta sozinho para recuperação protegida de conta.
Esse é o equilíbrio que queríamos: recuperação que pareça fácil, rápida e simples para o dono da conta, mas permaneça rigorosa o bastante para que adivinhar pelo servidor não seja um caminho prático.