Informática Numaboa - Tutoriais e Programação
Como as senhas são criptografadas no Joomla
Seg 15 Dez 2008 22:25 |
- Detalhes
- Categoria: Joomla
- Atualização: Segunda, 02 Julho 2012 19:45
- Autor: vovó Vicki
- Acessos: 10918
Meu amigo Tchó fez uma pergunta muito interessante: "Pretendo utilizar a tabela de usuários do Joomla para autenticar usuários em outras páginas que irei criar em um portal. Acontece que não sei como criptografar a senha digitada pelo usuário para comparar com a que está salva na tabela do BD do Joomla. Procurei muito pela Net mas ainda não encontrei... você poderia dar uma ajudinha?"
Claro que sim! E para que outros também possam usar estas informações, elas vão em forma de tutorial.
Antes de sujar a mão de graxa
Neste tutorial estou falando do método de encriptação de senhas do Joomla 1.5.x. Para reforçar a segurança deste CMS, estas versões apresentam um método bem mais robusto quando comparado com o método oferecido pelas versões mais antigas 1.0.x. Se você ainda não atualizou para a 1.5.x, está mais do que na hora de pensar em fazer isto - não só pelo aspecto segurança, mas também porque as versões 1.0.x vão ser descontinuadas.
Onde estão guardadas as informações
Não fui eu quem inventou o sistema de criptografia de senhas do Joomla, mas, como a criptografia é um dos meus assuntos preferidos, fui dar uma espiada no que a turma dos joomleiros fez. Localizei dois arquivos essenciais para entender a mecânica da cifragem: o primeiro é o arquivo joomla.php, que faz parte do plugin de autenticação; o segundo é o helper.php, que faz parte do conjunto de arquivos user da biblioteca joomla. Estão nos seguintes diretórios:
- /plugins/authentication/joomla.php
- /libraries/joomla/user/helper.php
Inicialmente abra o joomla.php e dê uma olhada no método onAutheticate:
Não é preciso destrinchar este código todinho (o que seria uma chatice), vou apenas apontar as partes que nos interessam. As linhas 70 a 78 mostram que o plugin acessou o banco de dados do Joomla para buscar algumas informações na tabela de usuários filtrando os dados pelo nome de usuário. Depois disto, se tiver encontrado alguma coisa, explode o que encontrou no campo password usando o delimitador ":" (linha 82). A primeira parte (a senha criptografada) é armazenada na variável $crypt; a segunda (o chamado sal) é colocada na variável $salt. Isto indica que as senhas guardadas são compostas por duas partes. Alguns exemplos são:
Logo a seguir, o método getCryptedPassword, que pertence à classe JUserHelper, é chamado com os parâmetros senha e sal (veja na linha 85). O que faz e onde está esta função? Na biblioteca do Joomla, mais especificamente no segundo arquivo que nos interessa: /libraries/joomla/user/helper.php. Veja a seguir o que são estas duas partes e como devem ser tratadas para que possamos conferir se determinado usuário está fornecendo a senha correta.
A criptografia das senhas do Joomla
No Joomla 1.0.x as senhas são transformadas num hash MD5. Se você não sabe o que é um hash, sugiro que dê uma lida nos artigos que publiquei em Criptografia/Funções Hash. Na versão atual, este hash foi incrementado (entenda-se, a segurança foi reforçada) adicionando-se um pouco de tempero, o chamado salt. A coisa funciona mais ou menos assim: "encomprida-se" a senha com mais uma porção de bits e só depois se aplica o hash MD5. Acontece que, se não soubermos qual salt foi usado para temperar a senha, não tem como repetir o processo para poder comparar a senha recém-fornecida com a senha que está no banco de dados. Daí separar a senha que foi "hasheada" junto com o sal do sal propriamente dito com o delimitador ":". Se tivermos os dois, o novo "hasheamento" pode ser comparado com o armazenado
Quem pode nos contar como todo este processo é realizado é o método getCryptedPassword da classe JUserHelper:
A função getCryptedPassword (linha 106) precisa no mínimo de um parâmetro: a senha em texto claro ($plaintext); os outros três parâmetros são opcionais. Se o sal ($salt) não for fornecido, ele recebe uma string vazia; se o tipo de encriptação ($encryption) não for definido, o valor padrão 'md5-hex' é assumido e se mostrar o tipo de encriptação ($show_encrypt) não for especificado, o padrão será falso. Em princípio, se chamarmos a função apenas com a senha fornecida pelo usuário, o sal não será usado, o tipo de cifragem será md5-hex e o tipo de encriptação não será adicionado ao resultado. É a cifragem mais simples que existe.
As linhas restantes desta função tratam de identificar o tipo de encriptação solicitado e realizam a cifragem de acordo. Para nós interessam apenas as linhas finais, onde o hash do tipo md5-hex é calculado. Se o sal estiver presente, a variável $encrypted recebe o valor de retorno da função do PHP md5() aplicada ao conjunto $plaintext.$salt; se não estiver presente, a mesma função do PHP é aplicada apenas a $plaintext. Da mesma forma, se $show_encrypt for verdadeiro, o tipo de cifragem é adicionado ao resultado pela concatenação de '{MD5}'.$encrypted; caso contrário, o valor de retorno será apenas o hash obtido.
Usando o banco de dados do Joomla fora do contexto Joomla
Agora que sabemos como as senhas são encriptadas antes de serem colocadas na tabela users é possível criar um código PHP próprio que busque informações no banco de dados do Joomla, fazer cifragens de senhas fornecidas pelos usuários e comparar os resultados. Digamos que temos um formulário com os campos usuario e senha. Este formulário aciona um script PHP que irá fazer a autenticação.
A primeira providência é buscar dados na tabela users. Para acessar o banco de dados do Joomla é preciso criar uma conexão:
Precisamos encontrar a senha cifrada do usuário indicado no formulário:
Tendo a senha criptografada, agora é preciso cifrar a senha fornecida pelo formulário e comparar as duas. Se a senha foi criptografada com um salt, sabemos que ela é composta por duas partes separadas pelo delimitador ":"; se não foi usado um salt, o delimitador não existe. Aqui podemos pegar uma carona no código do plugin para obter as partes da senha armazenada no banco de dados e depois completar o script com uma pequena rotina que cifra a senha fornecida pelo usuário e compara o resultado com a senha do banco de dados:
É claro que este script pode (e deve) ser melhorado. Por exemplo, deveria haver tratamento de erros como falha na conexão, etc. Mas este é apenas um esqueleto de script que serve somente para passar a idéia de como podemos implementar um sisteminha de checagem de senhas armazenadas no banco de dados do Joomla.
Grande abraço da vó