Informática Numaboa - Tutoriais e Programação
		
			Como as senhas são criptografadas no Joomla		
		
	
	
   
 
 - Detalhes
- 
										Categoria: Joomla						
- 
		Atualização: Segunda, 02 Julho 2012 19:45		
- 
				
							Autor: vovó Vicki				
- 
		Acessos: 11796		
				
			Pagina 2 de 3
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:
/**
 * Formats a password using the current encryption.
 *
 * @access  public
 * @param   string   $plaintext     The plaintext password to encrypt.
 * @param   string   $salt          The salt to use to encrypt the password. []
 *                                  If not present, a new salt will be
 *                                  generated.
 * @param   string   $encryption    The kind of pasword encryption to use.
 *                                  Defaults to md5-hex.
 * @param   boolean  $show_encrypt  Some password systems prepend the kind of
 *                                  encryption to the crypted password ({SHA},
 *                                  etc). Defaults to false.
 *
 * @return  string   The encrypted password.
 */
function getCryptedPassword($plaintext, $salt = '', $encryption = 'md5-hex', $show_encrypt = false)
{
   // Get the salt to use.
   $salt = JUserHelper::getSalt($encryption, $salt, $plaintext);
   // Encrypt the password.
   switch ($encryption)
   {
      case 'plain' :
         return $plaintext;
      case 'sha' :
         $encrypted = base64_encode(mhash(MHASH_SHA1, $plaintext));
         return ($show_encrypt) ? '{SHA}'.$encrypted : $encrypted;
      case 'crypt' :
      case 'crypt-des' :
      case 'crypt-md5' :
      case 'crypt-blowfish' :
         return ($show_encrypt ? '{crypt}' : '').crypt($plaintext, $salt);
      case 'md5-base64' :
         $encrypted = base64_encode(mhash(MHASH_MD5, $plaintext));
         return ($show_encrypt) ? '{MD5}'.$encrypted : $encrypted;
      case 'ssha' :
         $encrypted = base64_encode(mhash(MHASH_SHA1, $plaintext.$salt).$salt);
         return ($show_encrypt) ? '{SSHA}'.$encrypted : $encrypted;
      case 'smd5' :
         $encrypted = base64_encode(mhash(MHASH_MD5, $plaintext.$salt).$salt);
         return ($show_encrypt) ? '{SMD5}'.$encrypted : $encrypted;
      case 'aprmd5' :
         $length = strlen($plaintext);
         $context = $plaintext.'$apr1$'.$salt;
         $binary = JUserHelper::_bin(md5($plaintext.$salt.$plaintext));
         for ($i = $length; $i > 0; $i -= 16) {
            $context .= substr($binary, 0, ($i > 16 ? 16 : $i));
         }
         for ($i = $length; $i > 0; $i >>= 1) {
            $context .= ($i & 1) ? chr(0) : $plaintext[0];
         }
         $binary = JUserHelper::_bin(md5($context));
         for ($i = 0; $i < 1000; $i ++) {
            $new = ($i & 1) ? $plaintext : substr($binary, 0, 16);
            if ($i % 3) {
               $new .= $salt;
            }
            if ($i % 7) {
               $new .= $plaintext;
            }
            $new .= ($i & 1) ? substr($binary, 0, 16) : $plaintext;
            $binary = JUserHelper::_bin(md5($new));
         }
         $p = array ();
         for ($i = 0; $i < 5; $i ++) {
            $k = $i +6;
            $j = $i +12;
            if ($j == 16) {
               $j = 5;
            }
            $p[] = JUserHelper::_toAPRMD5((ord($binary[$i]) << 16) | (ord($binary[$k]) << 8) | (ord($binary[$j])), 5);
         }
         return '$apr1$'.$salt.'$'.implode('', $p).JUserHelper::_toAPRMD5(ord($binary[11]), 3);
      case 'md5-hex' :
      default :
         $encrypted = ($salt) ? md5($plaintext.$salt) : md5($plaintext);
         return ($show_encrypt) ? '{MD5}'.$encrypted : $encrypted;
   }
}
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.