thumbnail

Implementando Autenticação de Dois Fatores (2FA) com PHP Puro

Yuri do Monte Yuri do Monte | 4 min de leitura
há 2 semanas

A segurança de aplicações web é uma preocupação constante para desenvolvedores. Uma das maneiras mais eficazes de proteger contas de usuários contra acessos não autorizados é a Autenticação de Dois Fatores (2FA). Neste guia, vamos explorar uma implementação completa do algoritmo TOTP (Time-Based One-Time Password), o mesmo utilizado por aplicativos como Google Authenticator e Authy, usando apenas PHP puro, sem a necessidade de bibliotecas externas.


O que é TOTP e Por Que Usar?

O TOTP é um padrão aberto (RFC 6238) que gera um código numérico de 6 a 8 dígitos que muda em intervalos de tempo definidos, geralmente 30 segundos. Ele adiciona uma camada extra de segurança ao processo de login. Mesmo que um invasor descubra a senha de um usuário, ele ainda precisará do código dinâmico gerado no dispositivo do usuário (como um smartphone) para obter acesso.

A implementação de 2FA é uma das melhores práticas de segurança recomendadas pelo OWASP (Open Web Application Security Project) para mitigar riscos de roubo de credenciais.


Visão Geral do Projeto

O código que analisamos é uma solução completa e independente para adicionar 2FA a qualquer projeto PHP. Ele foi projetado para ser simples, leve e fácil de integrar, sem a necessidade de gerenciar dependências com o Composer.


Como Funciona: Por Dentro da Classe TOTP.php

O coração do sistema é a classe TOTP.php. Vamos entender seus principais métodos e como o algoritmo funciona.

1. Geração da Chave Secreta (generateSecret)

Tudo começa com uma chave secreta, que é compartilhada entre o servidor e o aplicativo autenticador do usuário. Esta chave é uma string aleatória codificada em Base32.

$totp = new TOTP();
$secret = $totp->generateSecret();
// Exemplo de output: JBSWY3DPEHPK3PXP


2. Geração do QR Code (getQRCodeImageUrl)

Para facilitar a vida do usuário, a chave secreta é geralmente apresentada como um QR Code. O aplicativo autenticador escaneia o código e armazena a chave.

$qrCodeUrl = $totp->getQRCodeImageUrl($secret, 'usuario@email.com', 'Nome do App');
echo '<img src="' . $qrCodeUrl . '">';


Este método utiliza uma API externa (qrserver.com) para gerar a imagem do QR Code a partir de uma URI no formato otpauth://.

3. Geração do Código (getCode)

O código de 6 dígitos é gerado usando a chave secreta e o tempo atual. O tempo é dividido em "janelas" de 30 segundos (o time step). Para cada janela de tempo, um código único é gerado.

O processo, de forma simplificada, é:


1.O time step atual é calculado (ex: floor(time() / 30)).

2.A chave secreta é decodificada de Base32 para binário.

3.Um HMAC (Hash-based Message Authentication Code) é calculado usando a chave secreta e o time step.

4.O resultado do HMAC é truncado para gerar um número de 6 dígitos.


4. Verificação do Código (verifyCode)

Quando o usuário insere o código de 6 dígitos, o servidor executa o mesmo processo de geração e compara o resultado com o código fornecido.

$userCode = '123456'; // Código inserido pelo usuário
$isValid = $totp->verifyCode($secret, $userCode);

if ($isValid) {
    // Acesso concedido
} else {
    // Acesso negado
}


Para compensar pequenas diferenças de relógio entre o servidor e o dispositivo do usuário, o método verifyCode também verifica os códigos da janela de tempo anterior e seguinte, garantindo uma melhor experiência de uso.

Integrando em Seu Projeto: Um Exemplo Completo

O arquivo 3_exemplo_completo.php demonstra um fluxo de login completo. Vamos resumir os passos:


1. Formulário de Login: O usuário insere email e senha.


2. Validação de Credenciais: O servidor verifica se o email e a senha estão corretos.


3. Tela de 2FA: Se as credenciais estiverem corretas, o usuário é redirecionado para uma segunda tela, onde deve inserir o código TOTP.


4. Verificação do Código TOTP: O servidor valida o código inserido usando o método verifyCode.


5. Sessão Autenticada: Se o código for válido, a sessão do usuário é marcada como totalmente autenticada e ele ganha acesso à área restrita do site.

Considerações de Segurança

Implementar 2FA aumenta muito a segurança, mas é crucial seguir algumas boas práticas:


• Armazenamento da Chave Secreta: A chave secreta (totp_secret) deve ser armazenada de forma criptografada no banco de dados. Nunca em texto plano.


• Comunicação Segura: Use sempre HTTPS para proteger a comunicação entre o cliente e o servidor.


• Rate Limiting: Limite o número de tentativas de verificação de código para prevenir ataques de força bruta.


• Códigos de Backup: Ofereça ao usuário um conjunto de códigos de backup de uso único, para o caso de ele perder o acesso ao seu dispositivo autenticador.

Conclusão

Adicionar uma camada de Autenticação de Dois Fatores não precisa ser uma tarefa complexa. Com esta implementação em PHP puro, você tem uma base sólida e confiável para fortalecer a segurança das suas aplicações. O código é transparente, fácil de auditar e livre de dependências, representando uma excelente opção para qualquer projeto PHP, do mais simples ao mais robusto.

Link repositório: https://github.com/yuri-spm/php-token


Discussions

Realize login para comentar neste post
Cláudio Víctor Cláudio Víctor . há 2 dias
Bacana 👏