ATUALIZAÇÃO: Recentemente, aprendi com esta pergunta que em toda a discussão abaixo, eu (e tenho certeza que outros também fizeram) fiquei um pouco confuso: O que eu continuo chamando de tabela de arco-íris, na verdade é chamado de tabela de hash. As tabelas de arco-íris são criaturas mais complexas e, na verdade, são uma variante de Hellman Hash Chains. Embora eu acredite que a resposta ainda seja a mesma (uma vez que não se resume à criptoanálise), parte da discussão pode ser um pouco distorcida.
A pergunta: " O que são tabelas arco-íris e como são usadas? "
Normalmente, eu sempre recomendo usar um valor aleatório criptograficamente forte como sal, para ser usado com funções hash (por exemplo, para senhas), como para proteção contra ataques de Rainbow Table.
Mas é realmente criptograficamente necessário que o sal seja aleatório? Qualquer valor exclusivo (exclusivo por usuário, por exemplo, userId) seria suficiente a esse respeito? Na verdade, impediria o uso de uma única tabela do arco-íris para quebrar todas (ou a maioria) das senhas no sistema ...
Mas a falta de entropia realmente enfraquece a força criptográfica das funções hash?
Observe, não estou perguntando sobre por que usar o salt, como protegê-lo (não precisa ser), usando um único hash constante (não) ou que tipo de função hash usar.
Apenas se o sal precisa de entropia ou não.
Obrigado a todos pelas respostas até agora, mas gostaria de me concentrar nas áreas com as quais estou (um pouco) menos familiarizado. Principalmente implicações para a criptoanálise - eu apreciaria muito se alguém tivesse alguma entrada do PoV criptomatemático.
Além disso, se houver vetores adicionais que não foram considerados, essa é uma ótima entrada também (consulte @Dave Sherohman point em vários sistemas).
Além disso, se você tiver alguma teoria, ideia ou prática recomendada - faça o backup com provas, cenário de ataque ou evidências empíricas. Ou mesmo considerações válidas para compensações aceitáveis ... Estou familiarizado com as Melhores Práticas (B maiúsculo P) sobre o assunto, gostaria de provar que valor isso realmente fornece.
EDIT: Algumas respostas muito boas aqui, mas acho que como @Dave diz, tudo se resume a Rainbow Tables para nomes de usuário comuns ... e possíveis nomes menos comuns também. No entanto, e se meus nomes de usuário forem globalmente exclusivos? Não necessariamente exclusivo para meu sistema, mas para cada usuário - por exemplo, endereço de e-mail.
Não haveria incentivo para construir um RT para um único usuário (como @Dave enfatizou, o salt não é mantido em segredo), e isso ainda impediria o agrupamento. O único problema seria que eu poderia ter o mesmo e-mail e senha em um site diferente - mas o sal não iria impedir isso de qualquer maneira.
Então, tudo se resume à criptoanálise - a entropia é necessária ou não? (Meu pensamento atual é que não é necessário do ponto de vista da criptoanálise, mas é por outras razões práticas.)
Respostas:
O sal é tradicionalmente armazenado como um prefixo da senha com hash. Isso já o torna conhecido por qualquer invasor com acesso ao hash de senha. Usar o nome de usuário como sal ou não não afeta esse conhecimento e, portanto, não teria efeito na segurança de um único sistema.
No entanto, usar o nome de usuário ou qualquer outro valor controlado pelo usuário como salt reduziria a segurança entre os sistemas, já que um usuário que tivesse o mesmo nome de usuário e senha em vários sistemas que usam o mesmo algoritmo de hash de senha acabaria com o mesmo hash de senha cada um desses sistemas. Não considero isso uma responsabilidade significativa porque eu, como um invasor, tentaria primeiro as senhas que uma conta de destino usou em outros sistemas antes de tentar qualquer outro meio de comprometer a conta. Hashes idênticos apenas me diriam com antecedência que a senha conhecida funcionaria, eles não tornariam o ataque real mais fácil. (Observe, porém, que uma comparação rápida dos bancos de dados de contas forneceria uma lista de alvos de prioridade mais alta, já que me diria quem está e quem não está reutilizando senhas.)
O maior perigo dessa ideia é que os nomes de usuário são comumente reutilizados - praticamente qualquer site que você queira visitar terá uma conta de usuário chamada "Dave", por exemplo, e "admin" ou "root" são ainda mais comuns - o que tornaria construção de rainbow tables direcionando usuários com esses nomes comuns muito mais fácil e eficaz.
Ambas as falhas podem ser resolvidas de forma eficaz adicionando um segundo valor de sal (fixo e oculto ou exposto como sal padrão) à senha antes de fazer o hash, mas, nesse ponto, você pode muito bem estar usando o sal entrópico padrão de qualquer maneira de trabalhar o nome de usuário nele.
Editado para adicionar: Muitas pessoas estão falando sobre entropia e se a entropia no sal é importante. É, mas não pelo motivo que a maioria dos comentários parecem pensar.
O pensamento geral parece ser que a entropia é importante para que o sal seja difícil para um invasor adivinhar. Isso é incorreto e, na verdade, completamente irrelevante. Como foi apontado algumas vezes por várias pessoas, os ataques que serão afetados pelo salt só podem ser feitos por alguém com o banco de dados de senhas e alguém com o banco de dados de senhas pode apenas verificar o que é o salt de cada conta. Se é possível adivinhar ou não, não importa quando você pode pesquisá-lo trivialmente.
A razão pela qual a entropia é importante é evitar o agrupamento de valores de sal. Se o salt é baseado no nome de usuário e você sabe que a maioria dos sistemas terá uma conta chamada "root" ou "admin", então você pode fazer uma tabela arco-íris para esses dois sais e isso quebrará a maioria dos sistemas. Se, por outro lado, um sal aleatório de 16 bits for usado e os valores aleatórios tiverem distribuição aproximadamente uniforme, você precisará de uma tabela arco-íris para todos os 2 ^ 16 sais possíveis.
Não se trata de impedir que o invasor saiba o que é o sal de uma conta individual, mas de não dar a ele o alvo grande e gordo de um único sal que será usado em uma proporção substancial de alvos em potencial.
fonte
Usar um sal de alta entropia é absolutamente necessário para armazenar senhas com segurança.
Pegue meu nome de usuário 'gs' e adicione-o à minha senha 'MyPassword' fornece gsMyPassword. Isso é facilmente quebrado usando uma rainbow-table porque se o nome de usuário não tiver entropia suficiente, pode ser que esse valor já esteja armazenado na rainbow-table, especialmente se o nome de usuário for curto.
Outro problema são os ataques em que você sabe que um usuário participa de dois ou mais serviços. Existem muitos nomes de usuário comuns, provavelmente os mais importantes são admin e root. Se alguém criou uma tabela de arco-íris com sais com os nomes de usuário mais comuns, ele poderia usá-los para comprometer contas.
Eles costumavam ter um sal de 12 bits . 12 bits são 4096 combinações diferentes. Isso não era seguro o suficiente porque tanta informação pode ser facilmente armazenada hoje em dia . O mesmo se aplica aos 4096 nomes de usuário mais usados. É provável que alguns de seus usuários escolham um nome de usuário que pertence aos nomes de usuário mais comuns.
Encontrei este verificador de senha que analisa a entropia de sua senha. Ter uma entropia menor nas senhas (como usar nomes de usuário) torna muito mais fácil para as tabelas do arco-íris, pois elas tentam cobrir pelo menos todas as senhas com baixa entropia, porque são mais prováveis de ocorrer.
fonte
É verdade que o nome de usuário sozinho pode ser problemático, pois as pessoas podem compartilhar nomes de usuários entre diferentes sites. Mas não deveria ser problemático se os usuários tivessem um nome diferente em cada site. Então, por que não torná-lo único em cada site. Hash a senha mais ou menos assim
função de hash ("www.yourpage.com /" + nome de usuário + "/" + senha)
Isso deve resolver o problema. Não sou um mestre em criptanálise, mas tenho certeza de que o fato de não usarmos alta entropia tornaria o hash mais fraco.
fonte
Gosto de usar os dois: um salt aleatório por registro de alta entropia, mais o ID exclusivo do próprio registro.
Embora isso não acrescente muito à segurança contra ataques de dicionário, etc., remove o caso marginal em que alguém copia seu salt e hash para outro registro com a intenção de substituir a senha por sua própria.
(Reconheço que é difícil pensar em uma circunstância em que isso se aplique, mas não vejo nenhum mal em cintos e suspensórios quando se trata de segurança.)
fonte
Se o sal for conhecido ou facilmente adivinhado, você não aumentou a dificuldade de um ataque de dicionário. Pode até ser possível criar uma tabela de arco-íris modificada que leve em consideração um sal "constante".
O uso de sais exclusivos aumenta a dificuldade de ataques de dicionário BULK.
Ter um valor de sal único e criptograficamente forte seria o ideal.
fonte
Eu diria que, desde que o sal seja diferente para cada senha, você provavelmente estará bem. O ponto principal é que você não pode usar a tabela rainbow padrão para resolver todas as senhas no banco de dados. Portanto, se você aplicar um sal diferente a cada senha (mesmo que não seja aleatório), o invasor basicamente terá que calcular uma nova tabela de arco-íris para cada senha, já que cada senha usa um sal diferente.
Usar um sal com mais entropia não ajuda muito, porque o invasor, neste caso, presume-se que já tenha o banco de dados. Uma vez que você precisa ser capaz de recriar o hash, você já deve saber o que é o sal. Portanto, você precisa armazenar o sal ou os valores que constituem o sal em seu arquivo. Em sistemas como o Linux, o método para obter o sal é conhecido, portanto, não adianta ter um sal secreto. Você deve presumir que o invasor que possui seus valores de hash provavelmente conhece seus valores de sal também.
fonte
A força de uma função hash não é determinada por sua entrada!
Usar um salt conhecido do invasor obviamente torna a construção de uma tabela de arco-íris (especialmente para nomes de usuário embutidos em código como root ) mais atraente, mas não enfraquece o hash . Usar um sal desconhecido para o invasor tornará o sistema mais difícil de atacar.
A concatenação de um nome de usuário e senha ainda pode fornecer uma entrada para uma tabela de arco-íris inteligente, portanto, usar um sal de uma série de caracteres pseudo-aleatórios, armazenados com a senha em hash, é provavelmente uma ideia melhor. Como ilustração, se eu tivesse o nome de usuário "batata" e a senha "cerveja", a entrada concatenada para seu hash seria "potatobeer", que é uma entrada razoável para uma tabela de arco-íris.
Alterar o salt cada vez que o usuário altera sua senha pode ajudar a derrotar ataques prolongados, como faria a aplicação de uma política de senha razoável, por exemplo, maiúsculas e minúsculas, pontuação, comprimento mínimo, alteração após n semanas.
No entanto, eu diria que sua escolha de algoritmo de resumo é mais importante. O uso de SHA-512 será mais doloroso para quem está gerando uma tabela arco-íris do que o MD5, por exemplo.
fonte
O sal deve ter o máximo de entropia possível para garantir que, se um determinado valor de entrada for hash várias vezes, o valor hash resultante será, o mais próximo possível, sempre diferente.
Usar valores de sal em constante mudança com o máximo de entropia possível no sal garantirá que a probabilidade de hash (digamos, senha + salt) produzirá valores de hash totalmente diferentes.
Quanto menos entropia no sal, mais chance você tem de gerar o mesmo valor de sal, pois, portanto, maior a chance de gerar o mesmo valor de hash.
É a natureza do valor hash ser "constante" quando a entrada é conhecida e "constante" que permite que ataques de dicionário ou tabelas de arco-íris sejam tão eficazes. Variando o valor de hash resultante tanto quanto possível (usando valores de sal de alta entropia) garante que o hash da mesma entrada + random-salt produzirá muitos resultados de valor de hash diferentes, derrotando (ou pelo menos reduzindo muito a eficácia) a tabela arco-íris ataques.
fonte
Entropia é o ponto de valor do Sal.
Se houver alguma "matemática" simples e reproduzível por trás do sal, então é o mesmo que o sal não está lá. Apenas adicionar valor ao tempo deve ser suficiente.
fonte