password_hash

(PHP 5 >= 5.5.0, PHP 7, PHP 8)

password_hashCria um hash de senha

Descrição

password_hash(#[\SensitiveParameter] string $password, string|int|null $algo, array $options = []): string

password_hash() cria um novo hash de senha usando um algoritmo forte de hash de mão única.

Os seguintes algoritmos são suportados atualmente:

  • PASSWORD_DEFAULT - Usa o algoritmo bcrypt (padrão desde o PHP 5.5.0). Perceba que essa constante foi desenhada para mudar ao longo do tempo a medida que novos algoritmos mais fortes forem adicionados ao PHP. Por essa razão, o comprimento do resultado da utilização desse identificador pode mudar ao longo do tempo. Por isso, é recomendado que armazene o resultado em uma coluna do banco de dados que possa ser expandida além dos 60 caracteres (255 caracteres seria uma boa escolha).
  • PASSWORD_BCRYPT - Usa o algoritmo CRYPT_BLOWFISH para criar o hash. Produzirá um hash compatível com o padrão crypt() usando o identificador "$2y$". O resultado será sempre uma string de 60 caracteres, ou false em caso de falha.
  • PASSWORD_ARGON2I - Usa o algoritmo Argon2i para criar o hash. Este algoritmo somente estará disponível se o PHP tiver sido compilado com suporte a Argon2.
  • PASSWORD_ARGON2ID - Usa o algoritmo Argon2is para criar o hash. Este algoritmo somente estará disponível se o PHP tiver sido compilado com suporte a Argon2.

Opções suportadas por PASSWORD_BCRYPT:

  • salt (string) - para fornecer manualmente um salt a ser usado quando estiver sendo feito o hash da senha. Perceba que isso irá sobrepor e evitar que um salt seja gerado automaticamente.

    Se omitido, um salt aleatório será gerado pela função password_hash() para cada senha sofrendo hash. Esse é o modo de operação desejado.

    Warning

    A opção salt está defasada. Agora é preferível que simplesmente se utilize o salt que é gerado por padrão. A partir do PHP 8.0.0, um salt fornecido explicitamente será ignorado.

  • cost (int) - indica o custo de algoritmo que deve ser usado. Exemplos desses valores podem ser encontrados na página da função crypt().

    Se omitido, um valor padrão 10 será usado. Este é um bom patamar de custo, mas pode-se considerar aumentar esse valor dependendo do hardware.

Opções suportadas por PASSWORD_ARGON2I e PASSWORD_ARGON2ID:

Parâmetros

password

A senha do usuário.

Caution

Usando PASSWORD_BCRYPT como algoritmo, resultará no parâmetro password sendo truncado em um comprimento máximo de 72 bytes.

algo

Uma constante de algoritmo de senha denotando o algoritmo a ser usado ao fazer o hash da senha.

options

Um array associativo contendo opções. Consulte as constantes de algoritmo de senha para obter a documentação sobre as opções suportadas por cada algoritmo.

Se omitido, um salt aleatório será gerado e o custo padrão será usado.

Valor Retornado

Retorna o hash da senha.

O algoritmo, o custo e o salt utilizados são retornados como parte do hash. Dessa forma, toda informação necessária para verificar o hash é incluída nele. Isso permite que a função password_verify() verifique o hash sem precisar de um armazenamento separado para a informação do salt ou do algoritmo.

Registro de Alterações

Versão Descrição
8.0.0 password_hash() não mais retorna false em caso de falha, em vez disso uma exceção ValueError será lançada se o algoritmo de hash da senha não for válido, ou uma exceção Error se o cálculo do hash falhou por motivo desconhecido.
8.0.0 O parâmetros algo agora pode ser nulo.
7.4.0 O parâmetro algo agora espera uma string, mas ainda aceita ints para compatibilidade com versões anteriores.
7.4.0 A extensão sodium fornece uma implementação alternativa para senhas Argon2.
7.3.0 Suporte para senhas Argon2id usando PASSWORD_ARGON2ID foi adicionado.
7.2.0 Suporte para senhas Argon2i usando PASSWORD_ARGON2I foi adicionado.

Exemplos

Example #1 Exemplo de password_hash()

<?php
/**
 * O objetivo é calcular o hash da senha usando o algortimo PASSWORD_DEFAULT atual.
 * Atualmente é BCRYPT, e resultará em uma string de 60 caracteres.
 *
 * Fique ciente que PASSWORD_DEFAULT pode mudar com o tempo, por isso deve-se
 * preparar para permitir strings com mais de 60 caracteres (255 é um bom número)
 */
echo password_hash("rasmuslerdorf", PASSWORD_DEFAULT);
?>

O exemplo acima produzirá algo semelhante a:

$2y$10$.vGA1O9wmRjrwAVXD98HNOgsNpDczlqm3Jq7KnEd1rVAGv3Fykk1a

Example #2 Exemplo de configuração do custo de password_hash() manualmente

<?php
/**
 * Neste caso, o objetivo é aumentar o custo padrão de BCRYPT para 12.
 * Note que agora o algortimo foi trocado para PASSWORD_BCRYPT, que sempre terá 60 caracteres.
 */
$options = [
    'cost' => 12,
];
echo password_hash("rasmuslerdorf", PASSWORD_BCRYPT, $options);
?>

O exemplo acima produzirá algo semelhante a:

$2y$12$QjSH496pcT5CEbzjD/vtVeH03tfHKFy36d4J0Ltp3lRtee9HDxY3K

Example #3 Exemplo de busca de um bom custo para password_hash()

<?php
/**
 * Este código irá verificar o desempenho do servidor para determinar o quanto pode-se aumentar
 * o custo. O objetivo é aumentar o custo ao valor mais alto possível sem deixar o servidor muito
 * lento. 10 é um bom ponto de partida, e um valor maior será bom se o servidor for
 * rápido o suficiente. O código abaix mira em ≤ 350 milissegundos de tempo adicional,
 * que é um atraso adequado para sistemas que lidam com logins interativos.
 */
$timeTarget = 0.350; // 350 milissegundos

$cost = 10;
do {
    $cost++;
    $start = microtime(true);
    password_hash("test", PASSWORD_BCRYPT, ["cost" => $cost]);
    $end = microtime(true);
} while (($end - $start) < $timeTarget);

echo "Custo Apropriado Encontrado: " . $cost;
?>

O exemplo acima produzirá algo semelhante a:

Custo Apropriado Encontrado: 12

Example #4 Exemplo de password_hash() usando Argon2i

<?php
echo 'Argon2i hash: ' . password_hash('rasmuslerdorf', PASSWORD_ARGON2I);
?>

O exemplo acima produzirá algo semelhante a:

Argon2i hash: $argon2i$v=19$m=1024,t=2,p=2$YzJBSzV4TUhkMzc3d3laeg$zqU/1IN0/AogfP4cmSJI1vc8lpXRW9/S0sYY2i2jHT0

Notas

Caution

É fortemente recomendado que não seja gerado um salt próprio para esta função. Ela criará um salt seguro automaticamente se um não for especificado.

Como apontado acima, fornecer a opção salt no PHP 7.0 gerará um erro deprecation warning. O suporte para fornecer um salt manualmente foi removido no PHP 8.0.

Note:

É recomendado que você teste esta função sem seus servidores, e ajuste o parâmetro custo para que a execução da função leve menos do que 350 milissegundos em sistemas interativos. O script do exemplo acima ajudará a escolher um bom valor de custo para seu hardware.

Note: Atualizações dos algoritmos suportados por esta função (ou alterações no algoritmo padrão) precisam seguir as seguintes regras:

  • Qualquer novo algoritmo precisa estar no core por pelo menos 1 versão completa do PHP antes de se tornar padrão. Assim se, por exemplo, um novo algoritmo for adicionado na versão 7.5.5, ela não seria elegível para padrão até a versão 7.7 (uma vez que a 7.6 seria a primeira versão completa). Mas se um algoritmo diferente for adicionado na versão 7.6.0, ela seria elegível para padrão na 7.7.0.
  • O padrão deve mudar apenas em uma versão completa (7.3.0, 8.0.8 etc.) e não em uma versão de revisão. A única exceção seria uma emergênca caso uma falha de segurança crítica fosse encontrada no padrão atual.

Veja Também