Estou tendo problemas para entender o propósito de um sal em uma senha. Entendo que o uso principal é dificultar um ataque à mesa do arco-íris. No entanto, os métodos que eu vi para implementar isso não parecem realmente tornar o problema mais difícil.
Eu já vi muitos tutoriais sugerindo que o sal seja usado da seguinte maneira:
$hash = md5($salt.$password)
O raciocínio é que o hash agora mapeia não a senha original, mas uma combinação da senha e do salt. Mas diga$salt=foo
e $password=bar
e $hash=3858f62230ac3c915f300c664312c63f
. Agora, alguém com uma tabela de arco-íris poderia reverter o hash e criar a entrada "foobar". Eles poderiam tentar todas as combinações de senhas (f, fo, foo, ... oobar, obar, bar, ar, ar). Pode demorar mais alguns milissegundos para obter a senha, mas não muito mais.
O outro uso que eu vi é no meu sistema linux. Na / etc / shadow, as senhas com hash são realmente armazenadas com o salt. Por exemplo, um sal de "foo" e senha de "bar" iria botar a este: $1$foo$te5SBM.7C25fFDu6bIRbX1
. Se um hacker conseguiu, de alguma forma, colocar as mãos nesse arquivo, não vejo a que finalidade o sal serve, já que o hash reverso te5SBM.7C25fFDu6bIRbX
é conhecido por conter "foo".
Obrigado por qualquer luz que alguém possa lançar sobre isso.
EDIT : Obrigado pela ajuda. Para resumir o que eu entendo, o salt torna a senha com hash mais complexa, tornando muito menos provável a existência em uma tabela arco-íris pré-computada. O que eu entendi errado antes foi que eu estava assumindo que uma tabela arco-íris existia para TODOS os hashes.
Respostas:
Um sal público não tornará os ataques de dicionário mais difíceis ao quebrar uma única senha. Como você apontou, o invasor tem acesso à senha com hash e ao salt; portanto, ao executar o ataque do dicionário, ele pode simplesmente usar o salt conhecido ao tentar decifrar a senha.
Um sal público faz duas coisas: torna mais demorado decifrar uma grande lista de senhas e torna inviável o uso de uma tabela arco-íris.
Para entender o primeiro, imagine um único arquivo de senha que contenha centenas de nomes de usuário e senhas. Sem um sal, eu poderia calcular "md5 (tentativa [0])" e depois percorrer o arquivo para ver se esse hash aparece em qualquer lugar. Se houver sais, devo calcular "md5 (sal [a]. Tentativa [0])", comparar com a entrada A e, em seguida, "md5 (sal [b]. Tentativa [0])", comparar com a entrada B Agora tenho
n
muito trabalho a fazer, onden
está o número de nomes de usuário e senhas contidos no arquivo.Para entender o segundo, você precisa entender o que é uma tabela arco-íris. Uma tabela arco-íris é uma grande lista de hashes pré-calculados para senhas usadas com freqüência. Imagine novamente o arquivo de senhas sem sais. Tudo o que tenho a fazer é percorrer cada linha do arquivo, retirar a senha com hash e procurá-la na tabela do arco-íris. Eu nunca tenho que calcular um único hash. Se a pesquisa for consideravelmente mais rápida que a função hash (que provavelmente é), isso acelerará consideravelmente a quebra do arquivo.
Mas se o arquivo da senha for salgado, a tabela do arco-íris deverá conter "salt. Password" pré-hash. Se o sal for suficientemente aleatório, isso é muito improvável. Provavelmente terei coisas como "olá", "foobar" e "qwerty" na minha lista de senhas pré-hash comumente usadas (tabela arco-íris), mas não terei coisas como "jX95psDZhello" ou "LPgB0sdgxfoobar" ou "dZVUABJtqwerty" pré-calculados. Isso tornaria a mesa arco-íris proibitivamente grande.
Portanto, o salt reduz o invasor de volta a uma computação por linha por tentativa, que, quando associada a uma senha suficientemente longa e aleatória, é (geralmente falando) invencível.
fonte
As outras respostas parecem não abordar seus mal-entendidos sobre o tópico, então aqui vai:
Dois usos diferentes de sal
Você sempre precisa armazenar o salt com a senha, pois, para validar o que o usuário digitou no seu banco de dados de senhas, é necessário combinar a entrada com o salt, fazer o hash e compará-lo com o hash armazenado.
Segurança do hash
Não é possível reverter o hash como tal (pelo menos em teoria). O hash de "foo" e o hash de "saltfoo" não têm nada em comum. Alterar um bit na entrada de uma função de hash criptográfico deve alterar completamente a saída.
Isso significa que você não pode construir uma tabela arco-íris com as senhas comuns e depois "atualizá-la" com algum sal. Você deve levar o sal em consideração desde o início.
Essa é toda a razão pela qual você precisa de uma tabela arco-íris em primeiro lugar. Como você não pode obter a senha do hash, pré-calcula todos os hashes das senhas usadas mais prováveis e, em seguida, compara seus hashes com os hashes.
Qualidade do sal
"foo" seria uma escolha extremamente pobre de sal. Normalmente você usaria um valor aleatório, codificado em ASCII.
Além disso, cada senha tem seu próprio sal, diferente (espero) de todos os outros sais no sistema. Isso significa que o invasor deve atacar cada senha individualmente, em vez de ter a esperança de que um dos hashes corresponda a um dos valores em seu banco de dados.
O ataque
Um ataque de tabela arco-íris sempre precisa
/etc/passwd
(ou qualquer banco de dados de senhas usado), ou então como você compararia os hashes na tabela arco-íris com os hashes das senhas reais?Quanto ao objetivo: digamos que o invasor queira criar uma tabela arco-íris para 100.000 palavras em inglês e senhas comuns usadas com frequência (pense em "segredo"). Sem sal, ela teria que pré-calcular 100.000 hashes. Mesmo com o tradicional sal UNIX de 2 caracteres (cada uma é uma das 64 opções
[a–zA–Z0–9./]
:), ela teria que calcular e armazenar 4.096.000.000 de hashes ... uma melhoria bastante.fonte
A idéia do sal é tornar muito mais difícil adivinhar com força bruta do que uma senha normal baseada em caracteres. As tabelas do arco-íris geralmente são criadas com um caractere especial definido em mente e nem sempre incluem todas as combinações possíveis (embora possam).
Portanto, um bom valor de sal seria um número inteiro aleatório de 128 bits ou mais. É isso que faz com que os ataques à tabela do arco-íris falhem. Ao usar um valor de sal diferente para cada senha armazenada, você também garante que uma tabela arco-íris criada para um valor de sal específico (como poderia ser o caso se você é um sistema popular com um único valor de sal) não lhe dá acesso a todos senhas de uma só vez.
fonte
Mais uma ótima pergunta, com muitas respostas bem pensadas - +1 a SO!
Um pequeno ponto que eu não vi explicitamente mencionado é que, adicionando um sal aleatório a cada senha, você praticamente garante que dois usuários que escolheram a mesma senha produzirão hashes diferentes.
Por que isso é importante?
Imagine o banco de dados de senhas em uma grande empresa de software no noroeste dos EUA. Suponha que ele contenha 30.000 entradas, das quais 500 possuem a senha em tela azul . Suponha ainda que um hacker consiga obter essa senha, digamos, lendo-a em um email do usuário ao departamento de TI. Se as senhas não tiverem sal, o hacker poderá encontrar o valor do hash no banco de dados e simplesmente corresponder ao padrão para obter acesso às outras 499 contas.
Salgar as senhas garante que cada uma das 500 contas tenha um único (salt + senha), gerando um hash diferente para cada uma delas e, assim, reduzindo a violação a uma única conta. E esperemos, com toda probabilidade, que qualquer usuário ingênuo o suficiente para escrever uma senha em texto sem formatação em uma mensagem de email não tenha acesso à API não documentada para o próximo SO.
fonte
Eu estava procurando por um bom método para aplicar sais e encontrei este excelente artigo com código de exemplo:
http://crackstation.net/hashing-security.htm
O autor recomenda o uso de sais aleatórios por usuário, para que o acesso a um sal não torne fácil a quebra de toda a lista de hashes.
fonte
A razão pela qual um sal pode fazer um ataque à mesa arco-íris falhar é que, para n bits de sal, a mesa arco-íris deve ser 2 ^ n vezes maior que o tamanho da mesa sem o sal.
Seu exemplo de usar 'foo' como sal pode tornar a mesa do arco-íris 16 milhões de vezes maior.
Dado o exemplo de Carl de um sal de 128 bits, isso torna a tabela 2 ^ 128 vezes maior - agora é grande - ou, em outras palavras, quanto tempo leva para que alguém tenha um armazenamento portátil tão grande?
fonte
A maioria dos métodos para quebrar a criptografia baseada em hash depende de ataques de força bruta. Um ataque do arco-íris é essencialmente um ataque de dicionário mais eficiente; foi projetado para usar o baixo custo do armazenamento digital para permitir a criação de um mapa de um subconjunto substancial de senhas possíveis para hashes e facilitar o mapeamento reverso. Esse tipo de ataque funciona porque muitas senhas tendem a ser bastante curtas ou usam um dos poucos padrões de formatos baseados em palavras.
Esses ataques são ineficazes no caso em que as senhas contêm muito mais caracteres e não estão em conformidade com formatos comuns baseados em palavras. Um usuário com uma senha forte para começar não ficará vulnerável a esse estilo de ataque. Infelizmente, muitas pessoas não escolhem boas senhas. Mas há um compromisso: você pode melhorar a senha de um usuário adicionando lixo aleatório a ela. Portanto, agora, em vez de "hunter2", sua senha pode se tornar efetivamente "hunter2908! Fld2R75 {R7 /; 508PEzoz ^ U430", que é uma senha muito mais forte. No entanto, como agora você precisa armazenar esse componente de senha adicional, isso reduz a eficácia da senha composta mais forte. Acontece que ainda existe um benefício líquido para esse esquema, já que agora cada senha, mesmo as mais fracas, não são mais vulneráveis à mesma tabela de hash / arco-íris pré-calculada. Em vez disso, cada entrada de hash da senha é vulnerável apenas a uma tabela de hash exclusiva.
Digamos que você tenha um site com requisitos de força de senha fracos. Se você não usar salt de senha, todos os seus hashes estarão vulneráveis a tabelas de hash pré-calculadas, alguém com acesso a seus hashes teria acesso às senhas para uma grande porcentagem de seus usuários (no entanto, muitas usavam senhas vulneráveis, o que seria uma percentagem substancial). Se você usar um salt de senha constante, as tabelas de hash pré-calculadas não serão mais valiosas; portanto, alguém teria que gastar tempo para calcular uma tabela de hash personalizada para esse salt, mas poderia fazê-lo de forma incremental, porém, tabelas de computação que cobrem permutações cada vez maiores do espaço do problema. As senhas mais vulneráveis (por exemplo, senhas simples baseadas em palavras, senhas alfanuméricas muito curtas) seriam decifradas em horas ou dias, senhas menos vulneráveis seriam decifradas após algumas semanas ou meses. Com o passar do tempo, um invasor obteria acesso a senhas para uma porcentagem cada vez maior de seus usuários. Se você usar um salt exclusivo para cada senha, levaria dias ou meses para obter acesso a cada uma dessas senhas vulneráveis.
Como você pode ver, quando você passa de um sal sem sal para um sal constante para um sal único, impõe um aumento de várias ordens de magnitude no esforço de quebrar senhas vulneráveis a cada etapa. Sem um salt, as senhas mais fracas de seus usuários são trivialmente acessíveis, com um sal constante essas senhas fracas são acessíveis a um invasor determinado, com um salt único, o custo de acessar senhas é tão alto que apenas o invasor mais determinado pode obter acesso para um pequeno subconjunto de senhas vulneráveis e, em seguida, apenas com grandes custos.
Qual é precisamente a situação em que você se encontra. Você nunca pode proteger completamente os usuários de uma escolha incorreta de senhas, mas pode aumentar o custo de comprometer as senhas de seus usuários a um nível que torne comprometedor mesmo a senha de um usuário proibitivamente cara.
fonte
Um dos objetivos da salga é derrotar tabelas de hash pré-computadas. Se alguém tiver uma lista de milhões de hashes pré-calculados, não poderá procurar US $ 1 $ foo $ te5SBM.7C25fFDu6bIRbX1 em sua tabela, mesmo sabendo o hash e o sal. Eles ainda terão que forçar a força bruta.
Outro objetivo, como Carl S menciona, é tornar o bruto forçar uma lista de hashes mais cara. (dê a todos diferentes sais)
Ambos os objetivos ainda são alcançados, mesmo que os sais sejam públicos.
fonte
Até onde eu sei, o sal é destinado a dificultar os ataques de dicionário.
É um fato conhecido que muitas pessoas usam palavras comuns para senhas em vez de seqüências aparentemente aleatórias.
Assim, um hacker poderia usar isso a seu favor, em vez de usar apenas força bruta. Ele não procurará senhas como aaa, aab, aac ... mas usará palavras e senhas comuns (como nomes do senhor dos anéis!;))
Portanto, se minha senha for Legolas, um hacker pode tentar fazer isso e adivinhar com "poucas" tentativas. No entanto, se saltarmos a senha e ela se tornar fooLegolas, o hash será diferente; portanto, o ataque ao dicionário não terá êxito.
Espero que ajude!
fonte
Suponho que você esteja usando a função PHP --- md5 () e variáveis $ precedidas ---, então você pode tentar ler este artigo HOWTO da Senha da Sombra Especialmente no parágrafo 11.
Além disso, você tem medo de usar algoritmos de compilação de mensagens, pode tentar algoritmos de criptografia reais, como os fornecidos pelo módulo mcrypt , ou algoritmos de compilação de mensagens mais fortes, como os que fornecem o módulo mhash (sha1, sha256 e outras).
Eu acho que um algoritmo mais forte de digestão de mensagens é obrigatório. Sabe-se que o MD5 e o SHA1 estão tendo problemas de colisão.
fonte