Análise detalhada de userverification

Este documento discute o que é userVerification na WebAuthn e os comportamentos do navegador que ocorrem quando userVerification é especificado durante a criação ou autenticação da chave de acesso.

O que é a "verificação de usuário" no WebAuthn?

As chaves de acesso são criadas com base na criptografia de chave pública. Ao criar uma chave de acesso, um par de chaves públicas/privadas é gerado, a chave privada é armazenada pelo provedor e a chave pública é retornada ao servidor da parte confiável (RP) para armazenamento. O servidor pode autenticar um usuário verificando uma assinatura assinada pela mesma chave de acesso usando a chave pública pareada. O flag "user presente" (UP) em uma credencial de chave pública prova que alguém interagiu com o dispositivo durante a autenticação.

A verificação do usuário é uma camada opcional de segurança que visa afirmar que a pessoa correta estava presente durante a autenticação, não apenas uma pessoa, como afirma a presença do usuário. Em smartphones, isso geralmente é feito usando o mecanismo de bloqueio de tela, seja com biometria, PIN ou senha. Se a verificação do usuário foi realizada, é informada na sinalização "UV" que é retornada nos dados do autenticador durante o registro e a autenticação da chave de acesso.

Captura de tela de uma caixa de diálogo de verificação do usuário com as Chaves do iCloud no macOS. A caixa de diálogo solicita que o usuário faça login usando o Touch ID, exibindo a origem que está solicitando a autenticação, bem como o nome de usuário. No canto superior direito da caixa de diálogo, há um botão chamado "Cancel".
Caixa de diálogo de verificação do usuário nas Chaves do iCloud no macOS.
Captura de tela de uma caixa de diálogo de verificação de usuário no Chrome para Android. A caixa de diálogo solicita que o usuário verifique a identidade usando reconhecimento facial ou detecção de impressão digital e exibe a origem que solicita a autenticação. No canto inferior esquerdo, há uma opção para fazer a verificação usando um PIN.
Caixa de diálogo de verificação do usuário no Chrome para Android.

Como UP e UV são validados no servidor

As sinalizações booleanas de presença do usuário (UP) e verificação do usuário (UV) são sinalizadas para o servidor no campo de dados do autenticador. Durante a autenticação, o conteúdo do campo de dados do autenticador pode ser validado verificando a assinatura com a chave pública armazenada. Contanto que a assinatura seja válida, o servidor pode considerar as sinalizações como genuínas.

Representação da estrutura de dados de autenticação. Da esquerda para a direita, cada seção da estrutura de dados lê "RP ID HASH" (32 bytes), "FLAGS" (1 byte), "COUNTER" (4 bytes, big-endian uint32), "ATTESTE CRED". DATA" (tamanho variável, se presente) e "EXTENSIONS" (tamanho variável se presente (CBOR)). A seção "FLAGS" é expandida para mostrar uma lista de possíveis flags, rotuladas da esquerda para a direita: "ED", "AT", "0", "BS", "BE", "UV", "0" e "UP".
Campos de dados do Authenticator em uma credencial de chave pública.

No registro e na autenticação da chave de acesso, o servidor precisa examinar se a flag UP é true e se ela é true ou false, dependendo do requisito.

Como especificar o parâmetro userVerification

De acordo com a especificação WebAuthn, a parte restrita pode solicitar uma verificação do usuário com um parâmetro userVerification na criação e declaração de credenciais. Ele aceita 'preferred', 'required' ou 'discouraged', o que significa, respectivamente:

  • 'preferred' (padrão): é preferível usar um método de verificação do usuário no dispositivo, mas ele pode ser ignorado se não estiver disponível. A credencial de resposta contém o valor da sinalização UV true, se a verificação do usuário tiver sido realizada, e false, se o UV não tiver sido realizado.
  • 'required': é necessário invocar um método de verificação do usuário disponível no dispositivo. Se não houver uma disponível, a solicitação falhará localmente. Isso significa que a credencial de resposta sempre retorna com a sinalização UV definida como true.
  • 'discouraged': não é recomendado usar um método de verificação do usuário. No entanto, dependendo do dispositivo, a verificação do usuário pode ser feita de qualquer maneira, e a sinalização UV pode conter true ou false.

Exemplo de código para criar uma chave de acesso:

const publicKeyCredentialCreationOptions = {
  // ...
  authenticatorSelection: {
    authenticatorAttachment: 'platform',
    residentKey: 'required',
    requireResidentKey: true,
    userVerification: 'preferred'
  }
};

const credential = await navigator.credentials.create({
  publicKey: publicKeyCredentialCreationOptions
});

Exemplo de código para autenticação da chave de acesso:

const publicKeyCredentialRequestOptions = {
  challenge: /* Omitted challenge data... */,
  rpId: 'example.com',
  userVerification: 'preferred'
};

const credential = await navigator.credentials.get({
  publicKey: publicKeyCredentialRequestOptions
});

Qual opção você deve escolher para userVerification?

O valor de userVerification que você precisa usar depende dos requisitos do aplicativo e da experiência do usuário.

Quando usar userVerification='preferred'

Use userVerification='preferred' se você priorizar a experiência do usuário em vez da proteção.

Há ambientes em que a verificação do usuário é mais atrito do que a proteção. Por exemplo, no macOS, em que o Touch ID não está disponível (porque o dispositivo não tem suporte, está desativado ou está no modo flip), o usuário precisa digitar a senha do sistema. Isso causa atrito, e o usuário pode abandonar a autenticação por completo. Se eliminar atritos for mais importante para você, use userVerification='preferred'.

Captura de tela de uma caixa de diálogo de chave de acesso no macOS que aparece quando o Touch ID não está disponível. A caixa de diálogo contém informações como a origem da solicitação de autenticação e o nome de usuário. No canto superior direito da caixa de diálogo, há um botão chamado "Cancel".
Caixa de diálogo de chave de acesso exibida no macOS quando o Touch ID não está disponível.

Com userVerification='preferred', a sinalização UV será true se a verificação do usuário for realizada com sucesso, e false se a verificação do usuário for ignorada. Por exemplo, no macOS, em que o Touch ID não está disponível, ele pede que o usuário clique em um botão para pular a verificação do usuário, e a credencial de chave pública inclui uma sinalização UV false.

Assim, a sinalização UV pode ser um sinal na sua análise de risco. Se a tentativa de login parecer arriscada devido a outros fatores, talvez seja necessário apresentar outros desafios de login ao usuário caso a verificação não tenha sido realizada.

Quando usar userVerification='required'

Use userVerification='required' se você achar que UP e UV são essenciais.

A desvantagem dessa opção é que o usuário pode ter mais dificuldades ao fazer login. Por exemplo, no macOS em que o Touch ID não está disponível, o usuário precisa digitar a senha do sistema.

Com userVerification='required', você pode garantir que a verificação do usuário seja realizada no dispositivo. Confira se o servidor verifica se a sinalização UV está true.

Conclusão

Ao aproveitar a verificação do usuário, as partes que confiam em chaves de acesso podem avaliar a probabilidade de o proprietário do dispositivo fazer login. É sua escolha entre exigir a verificação do usuário ou torná-la opcional, dependendo da importância do mecanismo de login alternativo para afetar o fluxo de usuários. Confira se o servidor verifica as sinalizações UP e UV para autenticação do usuário da chave de acesso.