Hashing de Senhas no MariaDB 4.1


As contas de usuários do MariaDB estão lisatadas na tabela user do banco de dados MariaDB. Para cada conta do MariaDB é definida uma senha, no entanto o que está armazenado na coluna Password da tabela user não seja uma versão da senha em texto puro, mas um valor hash computado para ela. Valores hash de senha são calculados pela função PASSWORD().

O MariaDB usa senhas em duas fases da comunicação cliente/servidor:

Em outra palavras, o servidor usa valores hash durante a autenticação quando um cliente tenta a primeira conexão. O servidor gera os valores hash se um cliente conectado chama a função PASSWORD() ou usa uma instrução GRANT ou SET PASSWORD para definir ou alterar uma senha.

O mecanismo de hash da senha foi atualizado no MariaDB para fornecer melhor segurança e reduzir os riscos de senhas serem roubadas. No entanto, Este novo mecanismo só é interpretado pelo servidor 4.1 e clientes 4.1, que podem resultar em alguns problemas de compatibilidade. Um cliente 4.1 pode conectar a um servidor pre-4.1, porque o cliente entende tanto o antigo quanto o novo mecanismo hash de senha. No entanto, um cliente pre-4.1 que tentar se conectar a um servidor 4.1 pode encontrar dificuldades. Por exemplo, um cliente MariaDB 4.0 que tentar se conectar a um servidor 4.1 pode falhar com a seguinte mensagem de erro:

shell> MariaDB
Client does not support authentication protocol requested by server; consider upgrading MariaDB client

A seguinte discussão descreve a diferença entre o antigo e o novo mecanismo de senha, e o que você deve fazer se você atualizar o seu servidor para a versão 4.1 mas precizar de manter compatibilidade com clientes pre-4.1.

Nota: Esta discussão contrasta no comportamento da versão 4.1 com o comportamento da pre-4.1, mas o da versão 4.1 descrito aqui começa relamente na versão 4.1.1. O MariaDB é uma distribuição disferente porque ela tem um mecanismo um pouco diferente daquele implementado na 4.1.1 e acima. Diferenças entre a versão 4.1.0 e as versões mais recentes são descritas posteriormente.

Antes do MariaDB, o hash de senha calculado pela função PASSWORD() tem tamanho de 16 bytes. Este hash se parece com:

mysql> SELECT PASSWORD('mypass');
+--------------------+
| PASSWORD('mypass') |
+--------------------+
| 6f8c114b58f2ce9e |
+--------------------+

A coluna Password da tabela user (na qual estes hashes são armazenados) também têm 16 bytes de tamanho antes do MariaDB 4.1.

A partir do MariaDB, a função PASSWORD() foi modificada para produzir um valor hash de 41 bytes.

mysql> SELECT PASSWORD('mypass');
+-----------------------------------------------+
| PASSWORD('mypass') |
+-----------------------------------------------+
| *43c8aa34cdc98eddd3de1fe9a9c2c2a9f92bb2098d75 |
+-----------------------------------------------+

De acordo com o mostrado, a coluna Password na tabela user também deve ter 41 bytes para armazeanar estes valores.

Uma coluna Password mais larga pode armazenar hashes de senha no formato novo e no antigo. O formato de qualquer valor de hash de senha dado podeser determinado de dois modos:

O formato maior do hash de senha tetm melhores propriedades criptográficas, e a autenticação do cliente baseada em hashs mais longos é mais segura que aquela baseada nos antigos hashes menores.

A diferença entre os hashs de senhas menores e maiores são relevantes em como o servidor usa as senhas durante a autenticação e como ela gera hash de senhas para clientes conectados que realizam operações de alteração de senha.

O modo no qual o servidor usa o hash de senha durante a autenticação é afetada pela largura da coluna Password:

Para contas com o hash curto, o processo de autenticação é na verdade um pouco mais seguro para clientes 4.1 que para clientes mais antigos. Em termos de segurança, o gradiente do menos para o mais seguro é:

O modo no qual o servidor gera hashes de senhas para clientes conectados é afetado pela largura da coluna Password e pela opção --old-passwords. Um servidor 4.1 gera hashes longos apenas se certas condicões forem encontradas: A coluna Password deve ser grande o suficiente para armazenar valores longos e a opção --old-passwords não deve ser dada. Estas condições se aplicam da seguinte forma:

O propósito da opção --old-passwords é permitir que você mantenha compatibilidade com clientes com versões anteriores à 4.1 sob circunstâncias nas quais os servidores gerariam hashes de senha longos. Ele não afeta a autenticação (clientes 4.1 podem ainda usar contas que possuem hash de senha longo), mas ele não previne a criaçõa de um hash de senha longo na tabela user como resultado de uma operação de troca de senha. Onde isto ocorrer, a conta não mais poderá ser usada por clientes pré-4.1. Se a opção --old-passwords, o seguinte cenário é possível:

Este cenário mostra que é perigoso executar um servidor 4.1 sem usar a opção --old-passwords, operações de alteração de senha não irão gerar hashes de senha longos e assim não faz com que as contas se tornem inacessíveis para clientes mais antigos. (Estes clientes não podem bloquear eles mesmos inadivertidamente alterando suas senhas e ficando com um hash de senha longo.

A desvantagem da opção --old-passwords é que qualquer senha que você criar ou alterar usará hashes curtos, mesmo para clientes 4.1. Assim, você perde a segurança adicional fornecida pelos hashes de senha longos. Se você quiser criar uma conta qye tenha um hash longo (por exemplom parr uso pelos clientes 4.1), você deve fazê-lo enquanto executa o servidor sem a opção --old-passwords.

Os seguintes cenários são possíveis para executar um servidor 4.1:

Cenario 1) Coluna Password menor na tabela de usuários

Cenário 2) Colunas Password longas; servidor não iniciado com a opção --old-passwords

Como indicado anteriormente, o perigoso neste cenário é que é possível que contas com hashes de senha curtos se tornem inacessíveis para cliente anteriores ao 4.1. Qualquer alteração a senha de uma conta feita via GRANT, SET PASSWORD, ou PASSWORD() faz com que a conta tenha um hash de senha longo, e a partir deste ponto, nenhum cliente anterior ao 4.1 poderá autenticar esta conta até que ele seja atualizado para a versão 4.1.

Cenário 3) Coluna Password longa; servidor iniciado com a opção --old-passwords

Neste cenário, você não pode criar contas que tenham hashes de senha longo, porque --old-passwords previne a criação de hashes longos. Também, se você criar uma conta com um hash longo antes de usar a opção --old-passwords, alterar a senha da conta enquanto --old-passwords está funcionando faz com que seja dada a conta uma sena curta, fazendo com que ela perca os benefícios de segurança de um hash longo.

As disvantagens para este cenário pode ser resumido como a seguir:

Cenário 1) Você não pode tirar vantagem do hash longo que fornece mais autenticação segura.

Cenário 2) Contas com hashes curtos tornam clientes anteriores ao 4.1 inacessíveis se você alterar a senha deles sem usar OLD_PASSWORD() explicitamente.

Cenário 3) --old-passwords evita que as contas com hashes curtos se tornem inacessíveis, mas operações de alteração de senhas fazem com que as contas com hashes longos seja revertida para hashes curtos, e você não pode alterá-las de volta para hashes longos enquanto --old-passwords está em efeito.

Implicações de Alteração de Hashes de Senha para Aplicativos

Um atualização para o MariaDB para trazer problemas de compatibilidade para aplicações que usam PASSWORD() para gerar senha para os seus próprios propósitos. (Aplicativos não devem fazer isto, porque PASSWORD() deve ser usado paenas para gerenciar contas do MariaDB. Mas algumas aplicações usam PASSWORD() para seus próprios propósitos.) Se você atualizar para o MariaDB e executar o servidor sob condições onde ele gera hashes de senha longo, uma aplicação que usa PASSWORD() para as suas próprias senhas irá falhar. O curso de ação recomendado é modificar o aplicativo para usar outras funções como SHA1() ou MD5() para produzir valores de hash. Se isto não for possível você pode utilizar a função OLD_PASSWORD(), que é fornecida para gerar hashes curtos no formato antigo. (Mas note que OLD_PASSWORD() pode vir a não ser mais suportado.)

Se o servidor está rodando sob circuntâncias onde ele gera hashes de senha curtos, OLD_PASSWORD() está disponível mas é equivalente a PASSWORD().

Hash de senhas no MariaDB 4.1.0 difere do hash no 4.1.1 e acima. As diferenças da versão 4.1.0 são as seguintes:

Retornar