Eu sempre usei uma string salt adequada por entrada ao fazer hash de senhas para armazenamento de banco de dados. Para minhas necessidades, armazenar o sal no banco de dados ao lado da senha com hash sempre funcionou bem.
No entanto, algumas pessoas recomendam que o sal seja armazenado separadamente do banco de dados. O argumento deles é que, se o banco de dados estiver comprometido, um invasor ainda poderá criar uma tabela arco-íris, levando em consideração uma sequência de sal específica, a fim de quebrar uma conta de cada vez. Se essa conta tiver privilégios de administrador, talvez ele nem precise quebrar nenhuma outra.
Do ponto de vista da segurança, vale a pena armazenar sais em um local diferente? Considere um aplicativo da web com o código do servidor e o banco de dados na mesma máquina. Se os sais forem armazenados em um arquivo simples nessa máquina, é provável que, se o banco de dados for comprometido, o arquivo de sais também será.
Existem soluções recomendadas para isso?
fonte
Respostas:
O ponto das tabelas arco-íris é que elas são criadas com antecedência e distribuídas em massa para economizar tempo de cálculo para outras pessoas - leva tanto tempo para gerar tabelas arco-íris em tempo real quanto seria necessário apenas quebrar a senha + a combinação de sal diretamente (desde efetivamente o que está sendo feito ao gerar tabelas arco-íris é pré-executar os cálculos para forçar brutalmente o hash); portanto, o argumento de que, conhecendo o sal, alguém poderia "gerar uma tabela arco-íris" é espúrio.
Não há nenhum ponto real em armazenar sais em um arquivo separado, contanto que eles sejam por usuário - o ponto principal é simplesmente fazê-lo para que uma tabela arco-íris não possa quebrar todas as senhas no banco de dados.
fonte
Vou fornecer uma visão um pouco diferente sobre isso.
Eu sempre guardo o sal misturado com o hash da senha salgada.
Por exemplo, colocarei a primeira metade do sal antes do hash salgado da senha e a última metade do sal após o hash salgado da senha. O aplicativo está ciente desse design para poder buscar esses dados e obter o hash salt e salted-password.
Minha justificativa para essa abordagem:
Se os dados de senha / hash forem comprometidos e caírem nas mãos de um invasor, o invasor não saberá o que é o sal olhando os dados. Dessa maneira, um invasor praticamente não pode executar um ataque de força bruta para obter uma senha que corresponda ao hash, pois ele não conhece o hash e não tem como saber quais partes dos dados são partes do sal, ou partes do hash de senha salgada (a menos que ele conheça a lógica de autenticação do seu aplicativo ).
Se o hash da senha salgada for armazenado como está, um ataque de força bruta poderá ser executado para obter uma senha que, quando salgada e com hash, produz os mesmos dados que o hash da senha com sal.
No entanto, por exemplo, mesmo que o hash da senha salgada tenha sido armazenado como está, mas pré-pendente com um único byte aleatório, desde que o invasor não saiba que esse primeiro byte deve ser descartado, isso também aumentaria a dificuldade de ataque. Seu aplicativo saberia descartar o primeiro byte dos dados quando usado para autenticar seu usuário.
A conclusão disso ..
1) Nunca armazene os dados que seu aplicativo de autenticação usa em sua forma exata.
2) Se possível, mantenha sua lógica de autenticação em segredo para aumentar a segurança.
Dê um passo adiante ..
Se você não pode manter em segredo a lógica de autenticação do aplicativo - muitas pessoas sabem como seus dados são armazenados no banco de dados. E suponha que você tenha decidido armazenar o hash da senha salgada misturado com o sal, com um pouco do sal precedido pelo hash da senha salgada e o restante do sal anexado.
Ao gerar o sal aleatório, você também pode decidir aleatoriamente qual proporção de sal armazenará antes / depois do hash da senha salgada.
Por exemplo, você gera um sal aleatório de 512 bytes. Você acrescenta o salt à sua senha e obtém o hash SHA-512 da sua senha salgada. Você também gera um número inteiro aleatório 200. Em seguida, armazena os primeiros 200 bytes do salt, seguidos pelo hash da senha salgada, seguido pelo restante do sal.
Ao autenticar a entrada de senha de um usuário, seu aplicativo passa a string e assume que o primeiro 1 byte dos dados é o primeiro 1 byte do salt, seguido pelo hash salgado. Este passe falhará. O aplicativo continuará usando os 2 primeiros bytes dos dados como os 2 primeiros bytes do salt e repetirá até que um resultado positivo seja encontrado após o uso dos primeiros 200 bytes como os primeiros 200 bytes do salt. Se a senha estiver incorreta, o aplicativo continuará tentando todas as permutações até que nenhuma seja encontrada.
Os profissionais dessa abordagem:
Maior segurança - mesmo que sua lógica de autenticação seja conhecida, a lógica exata é desconhecida no momento da compilação. É praticamente impossível realizar um ataque de força bruta, mesmo com o conhecimento da lógica exata. Comprimentos maiores de sal aumentarão ainda mais a segurança.
Os contras dessa abordagem:
Como a lógica exata é inferida em tempo de execução, essa abordagem é muito intensiva da CPU. Quanto maior o comprimento do sal, mais intensiva a CPU essa abordagem se torna.
A autenticação de senhas incorretas envolverá o custo mais alto da CPU. Isso pode ser contraproducente para solicitações legítimas, mas aumenta a segurança contra invasores.
Essa abordagem pode ser implementada de várias maneiras e pode ser ainda mais segura usando sais de largura variável e / ou hashes de senha salgada.
fonte
Geralmente, eles são anexados ao hash e armazenados no mesmo campo.
Não há necessidade de armazená-los separadamente - o objetivo é usar um sal aleatório para cada senha, para que uma única tabela do arco-íris não possa ser usada contra todo o conjunto de hashes de senha. Com sais aleatórios, um atacante deve aplicar força bruta a cada hash separadamente (ou calcular uma tabela do arco-íris para todos os sais possíveis - muito mais trabalho).
Se você tivesse um local de armazenamento mais seguro, faria sentido apenas armazenar os hashes lá.
fonte
Baseado no livro Developing ASP.NET MVC 4 Web Applications de William Penberthy:
fonte
O objetivo de um sal é tornar inúteis todas as tabelas do arco-íris e exigir a criação de um novo conjunto delas. Leva tanto tempo para adivinhar uma corda quanto para fazer uma mesa de arco-íris. Por exemplo, o hash SHA-256 de "senha" é
5e88 4898 da28 0471 51d0 e56f 8dc6 2927 7360 3d0d 6aab bdd6 2a11 ef72 1d15 42d8
. Após a adição de um salt, como "badpassword", a nova string a ser hash é "passwordbadpassword" que, devido ao efeito de avalanche, altera drasticamente a saída para457b f8b5 37f1 802e f9c8 2e46 b8d3 f8b5 721b 7cbb d485 f0bb e523 bfbe 73e6 58d6
.Normalmente, o salt é apenas armazenado no mesmo banco de dados que a senha, também porque se um banco de dados for invadido, é provável que o outro também seja.
fonte