SHA1 vs MD5 vs SHA256: qual usar para um login PHP?


133

Estou fazendo um login php e estou tentando decidir se deve usar SHA1 ou Md5 ou SHA256 sobre o qual li em outro artigo do stackoverflow. Algum deles é mais seguro que outros? Para o SHA1 / 256, ainda uso sal?

Além disso, esta é uma maneira segura de armazenar a senha como um hash no mysql?

function createSalt()
{
    $string = md5(uniqid(rand(), true));
    return substr($string, 0, 3);
}

$salt = createSalt();

$hash = sha1($salt . $hash);


Consulte também esta resposta e leia a seção sobre hash de senha.
Ja͢ck

Respostas:


110

Nem. Você deveria usar bcrypt. Os hashes mencionados são todos otimizados para serem rápidos e fáceis no hardware e, portanto, quebrá-los compartilham as mesmas qualidades. Se você não tiver outra escolha, use pelo menos um longo sal e misture novamente várias vezes.

Usando bcrypt no PHP 5.5 ou superior

O PHP 5.5 oferece novas funções para hash de senha . Essa é a abordagem recomendada para armazenamento de senha em aplicativos da web modernos.

// Creating a hash
$hash = password_hash($password, PASSWORD_DEFAULT, ['cost' => 12]);
// If you omit the ['cost' => 12] part, it will default to 10

// Verifying the password against the stored hash  
if (password_verify($password, $hash)) {
    // Success! Log the user in here.
}

Se você estiver usando uma versão mais antiga do PHP, realmente deve atualizar , mas até você pode usar password_compat para expor esta API.

Além disso, por favor, deixe password_hash()gerar o sal para você. Ele usa um CSPRNG .

Duas advertências de bcrypt

  1. Bcrypt silenciosamente truncará qualquer senha com mais de 72 caracteres.
  2. O Bcrypt truncará após qualquer NUL caractere.

( Prova de conceito para as duas ressalvas aqui.)

Você pode ficar tentado a resolver a primeira advertência pré-hash de suas senhas antes de executá-las no bcrypt , mas isso pode fazer com que seu aplicativo seja executado de cabeça no segundo.

Em vez de escrever seu próprio esquema, use uma biblioteca existente gravada e / ou avaliada por especialistas em segurança.

TL; DR - Use bcrypt .


1
Além disso, sou muito novo nisso: sha1, sha256 e md5 são todos os 'hashes' aos quais você se refere?
Tony Stark

3
Sim. Estou me referindo ao SHA1, SHA256 e MD5 e a uma série de outros hashes otimizados para velocidade. Você não deseja usar um hash otimizado para velocidade para proteger uma senha. Há muitos bons artigos discutindo o porquê, e eu gosto deste em particular: chargen.matasano.com/chargen/2007/9/7/…
Johannes Gorset

4
Está incluído na função "crypt" desde o PHP 5.3. Se você tem uma versão anterior, eu procuraria na estrutura "phpass" a próxima melhor coisa.
Johannes Gorset

3
@Stanislav Palatnik SHA512 é uma boa alternativa. Não me interpretem mal; Não estou dizendo que um hash estendido e salgado do SHA512 é inseguro. É seguro. Mesmo assim, permanece o fato de que o bcrypt é mais seguro e, portanto, não vejo razão para não usá-lo.
Johannes Gorset

10
@ Code: bcrypté projetado para ser lento, no interesse de ser igualmente lento para quebrar.
Johannes Gorset 16/03/2013

23

Eu acho que usar md5 ou sha256 ou qualquer hash otimizado para velocidade é perfeitamente bom e estou muito curioso para ouvir qualquer refutação que outros usuários possam ter. Aqui estão as minhas razões

  1. Se você permitir que os usuários usem senhas fracas, como Deus, amor, guerra, paz, não importa a criptografia, você ainda permitirá que o usuário digite a senha, não o hash, e essas senhas são usadas primeiro, portanto, NÃO vai acontecer. ter algo a ver com criptografia.

  2. Se você não estiver usando SSL ou não tiver um certificado, os invasores que estiverem ouvindo o tráfego poderão extrair a senha e qualquer tentativa de criptografar com javascript ou similar é do lado do cliente e é facilmente quebrada e superada. Novamente, isso NÃO terá nada a ver com a criptografia de dados no lado do servidor.

  3. Os ataques de força bruta tirarão proveito de senhas fracas e novamente, porque você permite que o usuário insira os dados se você não tiver a limitação de logon de 3 ou até um pouco mais do que o problema novamente NÃO terá nada a ver com criptografia de dados.

  4. Se seu banco de dados for comprometido, provavelmente tudo foi comprometido, incluindo suas técnicas de hash, não importa o quão enigmático você o tenha criado. Novamente, isso pode ser um ataque XSS de funcionário descontente ou injeção de sql ou algum outro ataque que não tem nada a ver com a criptografia de senha.

Eu acredito que você ainda deve criptografar, mas a única coisa que consigo ver é a criptografia, para impedir que as pessoas que já tenham ou de alguma forma obtiveram acesso ao banco de dados leiam em voz alta a senha. Se é alguém não autorizado no banco de dados, você tem problemas maiores para se preocupar, por isso a Sony foi pega porque eles pensaram que uma senha criptografada protegia tudo, incluindo números de cartão de crédito, tudo o que ele faz é proteger esse campo.

O único benefício puro que posso obter para criptografias complexas de senhas em um banco de dados é atrasar os funcionários ou outras pessoas que têm acesso ao banco de dados apenas lendo as senhas. Portanto, se for um projeto pequeno ou algo do tipo, eu não me preocuparia muito com a segurança no lado do servidor. Em vez disso, me preocuparia mais com a segurança de qualquer coisa que um cliente possa enviar ao servidor, como injeção de sql, ataques XSS ou muitas outras maneiras de você pode ser comprometida. Se alguém discordar, espero ler de uma maneira que uma senha super criptografada é uma obrigação do lado do cliente.

O motivo pelo qual eu queria tentar esclarecer isso é porque, com muita frequência, as pessoas acreditam que uma senha criptografada significa que não precisam se preocupar com o comprometimento da senha e deixam de se preocupar com a segurança do site.


1
Bem afirmado. A segurança cibernética será preferida às técnicas de hash, além de salvar seus dados, mas também manter a defesa do servidor pronta.
CᴴᴀZ

14
Isso é realmente mal informado. É claro que o hash de senhas com segurança no banco de dados não melhora a segurança no nível do aplicativo ou no banco de dados. Não é um problema para a segurança. Você deseja hash com segurança a senha do usuário no seu banco de dados por 2 razões; primeiro, o cliente está confiando em você a senha, que eles podem ou não usar em outros sites; portanto, você quer garantir que isso não seja recuperável, mesmo se o banco de dados estiver comprometido; segundo, você deseja remover a responsabilidade em caso de segurança violação. Não conheço nenhuma ação judicial de imediato, mas o vazamento de senhas faz a sua empresa parecer muito ruim.
James McMahon

6
Este é um mau conselho. Se alguém rouba seu banco de dados e obtém todas as suas senhas com hash, mesmo que elas também tenham comprometido outras partes do banco de dados, ainda assim pode ser importante impedir que ele decifre as senhas e faça logon. (Pense em um site bancário, por exemplo.) Os algoritmos com velocidade otimizada permitem que os atacantes testem muitos candidatos contra os hashes roubados até encontrar uma correspondência. Algoritmos como bcrypt e scrypt tornam lento e caro testar candidatos contra o hash, mesmo que eles saibam qual algoritmo você usa. Então, eles oferecem melhor proteção se alguém roubar os hashes.
Richard

6
"Se o seu banco de dados ficar comprometido, provavelmente tudo foi comprometido, incluindo suas técnicas de hash, não importa o quão enigmático você o tenha criado." É por isso que o bcrypt é tão importante. Com o bcrypt, realmente não importa se alguém tem os hashes. Com um algoritmo de hash rápido como o SHA1 / MD5, ele faz.
ceejayoz

Eu acho que o ponto que alguns de vocês estão perdendo é que não importa se a senha é 1000% segura quando todos os outros dados estão em texto não criptografado. Por exemplo, se o banco de dados inteiro estiver comprometido, o hacker agora terá todos os números de cartão de crédito em texto não criptografado. Sim, muitas pessoas usam a mesma senha em sites diferentes, mas eles já foram instruídos no ad nauseum a não fazer isso, então não é mais um problema nosso. Se o próprio banco de dados contiver informações confidenciais e seu comprometimento for uma preocupação, criptografe o banco de dados inteiro, o mais forte que achar necessário.
precisa saber é o seguinte

15

Como Johannes Gorset apontou, a postagem de Thomas Ptacek, da Matasano Security, explica por que funções simples de hash de uso geral, como MD5, SHA1, SHA256 e SHA512, são más escolhas de hash de senha .

Por quê? Eles são muito rápidos - você pode calcular pelo menos 1.000.000 de hashes MD5 por segundo por núcleo em um computador moderno, para que a força bruta seja possível contra a maioria das senhas que as pessoas usam. E isso é muito menos do que um cluster de servidores de cracking baseado em GPU!

Salgar sem esticar a chave significa apenas que você não pode pré-calcular a tabela do arco-íris; é necessário construí-la ad hoc para esse sal específico. Mas isso não tornará as coisas muito mais difíceis.

O usuário @Will diz:

Todo mundo está falando sobre isso como se eles pudessem ser invadidos pela Internet. Como já foi dito, limitar as tentativas torna impossível quebrar uma senha pela Internet e não tem nada a ver com o hash.

Eles não precisam. Aparentemente, no caso do LinkedIn, eles usaram a vulnerabilidade de injeção SQL comum para obter a tabela do banco de dados de login e quebraram milhões de senhas offline.

Depois, ele volta ao cenário de ataque offline:

A segurança realmente entra em jogo quando todo o banco de dados é comprometido e um hacker pode executar 100 milhões de tentativas de senha por segundo no hash md5. O SHA512 é cerca de 10.000 vezes mais lento.

Não, o SHA512 não é 10000 vezes mais lento que o MD5 - leva apenas o dobro. O Crypt / SHA512 , por outro lado, é uma fera muito diferente que, como sua contraparte do BCrypt, executa um alongamento de chave , produzindo um hash muito diferente com um sal aleatório incorporado e levará algo entre 500 e 999999 vezes mais para calcular (o alongamento é ajustável).

SHA512 => aaf4c61ddcc5e8a2dabede0f3b482cd9aea9434d
Crypt/SHA512 => $6$rounds=5000$usesomesillystri$D4IrlXatmP7rx3P3InaxBeoomnAihCKRVQP22JZ6EY47Wc6BkroIuUUBOov1i.S5KPgErtP/EN5mcO.ChWQW21

Portanto, a opção para PHP é Crypt / Blowfish (BCrypt), Crypt / SHA256 ou Crypt / SHA512. Ou pelo menos Crypt / MD5 (PHK). Veja www.php.net/manual/en/function.crypt.php


O hash simples de senha é bom, cabe ao firewall manter o servidor seguro. Por "firewall", refiro-me a um firewall reativo que bloqueia / desacelera a força bruta (um humano pode digitar tão rápido) .. O concurso é inútil .. "e se algum hacker invadisse e agora tivesse tudo" (de frente) - se um hacker entrar no seu servidor - acabou. As senhas são quebradas principalmente porque são muito simples ou os desenvolvedores de software são muito preguiçosos para pensar como um cibercriminoso.

@argon Por favor, leia novamente. Todo o objetivo do hash de senhas é para que, quando seu banco de dados de login for comprometido (e em algum momento), você não vaze imediatamente todas as senhas de seus usuários, que são mais frequentemente reutilizadas pelos usuários em sites diferentes - caso contrário, uma simples atraso após a entrada faria. E o "fim do jogo se eles entraram no seu servidor" é um ponto discutível, porque eles não precisam entrar no servidor. A vulnerabilidade mais comum usada pelos hackers foi a injeção de SQL (consulte o caso do Linkedin), e eles reforçam o hash. É por isso que você precisa de salga e alongamento.
LexLythius

se o requisito de segurança for realmente tão intenso, o armazenamento de senhas em outros lugares pode ser uma boa ideia. Existem várias maneiras de proteger seus dados (e código-fonte) -para "se / quando" ... .. -mas hash de senhas até um "bilhão de bits" é tão seguro quanto: o criador da senha / sistema convidado , a transmissão de dados e os seres humanos que atendem ao hardware do servidor. .. Dito isto: NÃO estou dizendo que o hash é inútil, no entanto, estou dizendo que se a sua solução for apenas hashes mais complicados, receio que não funcione no futuro próximo, em relação aos computadores quânticos.

O hash recursivo adiciona trabalho / custo a qualquer tentativa de invasão. Quanto mais iterações, mais difícil de quebrar, portanto, até hashes rápidos como o SHA256 poderiam ser usados. As iterações devem ser aleatórias e podem ser tornadas públicas. password_hash()mostra o custo no próprio hash.
Victor Stoddard

@VictorStoddard Sim, você pode rolar seu próprio esquema de hash e fornecer alongamento de chave ajustável. Mas por que você gostaria de fazer isso em vez de usar algoritmos já existentes e muito mais minuciosamente examinados, criados por especialistas e disponibilizados exatamente para esse fim?
LexLythius 27/02/19

13

Use SHA256. Não é perfeito, como SHA512seria ideal para um hash rápido, mas dentre as opções, é a escolha definitiva. Como em qualquer tecnologia de hash, certifique-se de salgar o hash para aumentar a segurança.

Como observação adicional, FRKT, mostre-me onde alguém pode facilmente quebrar um hash SHA256 salgado? Estou realmente muito interessado em ver isso.

Edição importante:

Avançando, use bcryptcomo um hash endurecido. Mais informações podem ser encontradas aqui .


Editar sobre salga:

Use um número aleatório ou fluxo de bytes aleatório etc. Você também pode usar o campo exclusivo do registro em seu banco de dados como o salt, desta forma o salt é diferente por usuário.


1
Mas eles são otimizados para velocidade, o que significa que eles permitem ataques de força bruta.
Arbales

6
Fato permanece, isso é para proteger uma senha. Ao usar um hash com sal e, em seguida, adicionar um limite de três tentativas no site, você diminui substancialmente as tentativas de hackers (até forçadoras brutas). Usando qualquer criptografia pura, agora você tem outro problema - proteger a chave. Se a chave for encontrada, seu banco de dados inteiro estará comprometido (se nenhum sal for adicionado). Hashes, no entanto, você nunca obterá a senha original do sistema, e é assim que deve ser.
Kyle Rosendo

1
Como observado, o problema com as séries MD e SHA é que elas são otimizadas para velocidade. É inevitável que hashes dessa natureza se tornem cada vez mais inseguros à medida que a computação evolui.
Johannes Gorset

1
Qualquer coisa se torna cada vez mais ruim / insegura / etc, à medida que a computação evolui. Quando o SHA512 etc. for invadido, haverá algoritmos mais seguros disponíveis. Essa é a natureza da computação em qualquer caso.
Kyle Rosendo

1
qual é uma boa maneira de fazer um sal em php? tem código de exemplo? Imagino que não deve apenas escolher algo como 'girafa'
Tony Stark

4

O que as pessoas parecem estar perdendo é que, se o hacker tiver acesso ao banco de dados, ele provavelmente também terá acesso ao arquivo php que contém a senha e provavelmente pode apenas modificar isso para enviar a ele todos os combos de senha de nome de usuário bem-sucedidos. Se ele não tiver acesso ao diretório da web, ele poderá sempre escolher uma senha, e escrever isso no banco de dados. Em outras palavras, o algoritmo de hash realmente não importa tanto quanto a segurança do sistema, e limitando as tentativas de login também se você não usar SSL, o invasor pode apenas ouvir a conexão para obter as informações. A menos que você precise que o algoritmo demore muito tempo para calcular (para seus próprios fins), o SHA-256 ou SHA-512 com um sal específico do usuário deve ser suficiente.

Como medida de segurança adicional, configure um script (bash, lote, python, etc) ou programa, atribua um nome obscuro e verifique se o login.php foi alterado (verifique a data / hora) e envie um email se tiver. Provavelmente, também deve registrar todas as tentativas de logon com direitos de administrador e todas as tentativas com falha de logon no banco de dados e receber os logs por e-mail.


"O que as pessoas parecem estar perdendo é que, se o hacker tiver acesso ao banco de dados, ele provavelmente também terá acesso ao arquivo php que contém a senha ..." Isso não é verdade. Uma das vulnerabilidades mais comuns é a injeção de SQL, que daria capacidade de leitura / gravação ao banco de dados, mas zero acesso ao código PHP.
ceejayoz

Se você tiver acesso ao código, poderá modificar e armazenar toda a senha que o usuário estiver enviando em texto sem formatação. Portanto, não, se o código for comprometido, GAME OVER.
magallanes

3

Todo mundo está falando sobre isso como se eles pudessem ser invadidos pela Internet. Como já foi dito, limitar tentativas impossibilita a quebra de uma senha pela Internet e não tem nada a ver com o hash.

O sal é uma obrigação, mas a complexidade ou vários sais nem sequer importam. Qualquer sal sozinho impede o atacante de usar uma mesa arco-íris pré-fabricada. Um sal único por usuário impede que o invasor crie uma nova tabela arco-íris para usar em toda a sua base de usuários.

A segurança realmente entra em jogo quando todo o banco de dados é comprometido e um hacker pode executar 100 milhões de tentativas de senha por segundo no hash md5. O SHA512 é cerca de 10.000 vezes mais lento. Uma senha complexa com o poder de hoje ainda pode levar 100 anos para bruteforce com md5 e levaria 10.000 vezes mais tempo com o SHA512. Os sais não impedem a força bruta, como sempre precisam ser conhecidos; se o invasor baixou seu banco de dados, ele provavelmente estava no seu sistema de qualquer maneira.


1

O MD5 está ruim por causa de problemas de colisão - duas senhas diferentes possivelmente gerando o mesmo md-5.

Sha-1 seria bastante seguro para isso. O motivo pelo qual você armazena a versão sha-1 salgada da senha é para que o swerver não mantenha a senha do usuário no arquivo, para que ele possa estar usando com os servidores de outras pessoas. Caso contrário, que diferença isso faz?

Se o hacker roubar todo o seu banco de dados não criptografado de alguma forma, a única coisa que uma senha salgada com hash faz é impedi-lo de se passar por usuário para futuras conexões - o hacker já possui os dados.

De que adianta o invasor ter o valor de hash, se o que o usuário digitar for uma senha simples?

E mesmo que o hacker com tecnologia futura pudesse gerar um milhão de chaves sha-1 por segundo para um ataque de força bruta, seu servidor gerenciaria um milhão de logons por segundo para o hacker testar suas chaves? Isso se você estiver permitindo que o hacker tente fazer logon com o sha-1 salgado em vez de uma senha como um logon normal.

A melhor aposta é limitar as tentativas incorretas de logon a um número razoável - 25 por exemplo, e depois o tempo limite do usuário por um ou dois minutos. E se a tentativa de logon cumulativo de bady atingir 250 em 24 horas, feche o acesso à conta e envie um e-mail ao proprietário.


Mesmo se eu estiver usando uma criptografia mais fraca, praticamente nenhum sistema pode conter um ataque bruto por mais de 1 milhão de tentativas por segundo.
magallanes

1
Três logins com falha e você está bloqueado. Período, fim da história. Até senhas super estúpidas como "1234" são seguras, se o hacker tentar primeiro "password", "pa $$ word" e "passw0rd" (travar!). Como o usuário recupera o acesso agora se torna seu ponto de discórdia, e o que você faz depende do tamanho da sua base de usuários. 200 usuários? Peça-lhes que telefonem para obter ajuda.
precisa saber é o seguinte

Essa resposta não faz sentido para mais ninguém, ou sou apenas eu?
Curinga

1

Aqui está a comparação entre MD5 e SHA1. Você pode ter uma idéia clara sobre qual é o melhor.

insira a descrição da imagem aqui


1

Use argon2i . A função de hash de senha do argon2 venceu a Competição de Hashing de Senhas.

Outras opções razoáveis, se o uso do argon2 não estiver disponível, são scrypt , bcrypt e PBKDF2 . A Wikipedia possui páginas para estas funções:

MD5, SHA1 e SHA256 são resumos de mensagens, não funções de hash de senha. Eles não são adequados para esse fim.

Mudar de MD5 para SHA1 ou SHA512 não aumentará muito a segurança da construção. A computação de um hash SHA256 ou SHA512 é muito rápida. Um invasor com hardware comum ainda pode tentar dezenas de milhões (com uma única CPU) ou até bilhões (com uma única GPU) de hashes por segundo. Boas funções de hash de senha incluem um fator de trabalho para retardar ataques de dicionário.

Aqui está uma sugestão para os programadores de PHP: leia as Perguntas frequentes sobre PHP e use password_hash () .


0

Vamos assumir o próximo ponto: os hackers roubam nosso banco de dados, incluindo os usuários e a senha (criptografados). E os hackers criaram uma conta falsa com uma senha que eles conhecem.

O MD5 é fraco porque é curto e popular e praticamente toda geração de hash sem senha é um ataque de dicionário fraco. Mas..

Então, digamos que ainda estamos usando o MD5 com um SALT. Os hackers não conhecem o SALT, mas sabem a senha de um usuário específico. Para que eles possam testar: 12345 onde 12345 é a senha conhecida e ????? é o sal. Os hackers, mais cedo ou mais tarde, podem adivinhar o SALT.

No entanto, se usamos um MD5 + SALT e aplicamos o MD5, não há como recuperar as informações. No entanto, repito, o MD5 ainda é curto.

Por exemplo, digamos que minha senha seja: 12345. O SALT é BILLCLINTON

md5: 827ccb0eea8a706c4c34a16891f84e7b

md5 com o hash: 56adb0f19ac0fb50194c312d49b15378

mD5 com o hash sobre md5: 28a03c0bc950decdd9ee362907d1798a Tentei usar esses serviços online e não encontrei nenhum que pudesse quebrá-los. E é o único MD5! (pode ser como hoje será crackable porque eu gerei o md5 online)

Se você deseja exagerar, o SHA256 é mais que suficiente se for aplicado com sal e duas vezes.

tldr MD5 (HASH + MD5 (senha)) = ok, mas curto, o SHA256 é mais que suficiente.


O problema do uso do MD5 com sal é que os computadores podem criar um ataque de força bruta à senha com velocidades super rápidas. Shylor.com/2015/09/14/php-5-5-secure-password-hashing
Shylor

0

Uma criptografia md5 é uma das piores, porque você precisa ativar o código e ele já está descriptografado. Eu recomendaria o SHA256. Estou programando um pouco mais e tive uma boa experiência. Abaixo também seria uma criptografia.

password_hash() example using Argon2i

<?php
echo 'Argon2i hash: ' . password_hash('rasmuslerdorf', PASSWORD_ARGON2I);
?>
The above example will output something similar to:

Argon2i hash: $argon2i$v=19$m=1024,t=2,p=2$YzJBSzV4TUhkMzc3d3laeg$zqU/1IN0/AogfP4cmSJI1vc8lpXRW9/S0sYY2i2jHT0
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.