Senhas de aplicativos da Web: bcrypt e SHA256 (e scrypt)

Com todas as discussões recentes (por exemplo, LinkedIn) de senhas, estou olhando para implementações de hash de senha. Depois de duas xícaras de café e uma manhã lendo eu não sou mais um criptógrafo do que quando eu comecei. E eu realmente não quero fingir que sou.

Questões Específicas

O uso de um ID de usuário único inteiro falha como um sal efetivo? (crypt () usa apenas 16 bits?)

Se eu simplesmente executar sha256 () em um hash repetidamente até que um segundo seja usado, isso derrota os ataques de força bruta?

Se eu tiver que fazer essas perguntas, devo usar o bcrypt?

Discussão / Explicação:

O objetivo é simplesmente se as senhas hash dos usuários vazaram:

não seria "fácil" de quebrar,quebrar uma senha não expõe outros usuários que usam a mesma senha).

O que eu li para o número 1 é que a computação hash deve ser cara - levando, digamos, um segundo ou dois para calcular e talvez exigir um bit ou memória (para impedir a descriptografia de hardware).

O bcrypt tem isso embutido, e o scrypt, se bem entendi, é mais preparado para o futuro e inclui um requisito mínimo de uso de memória.

Mas, é uma abordagem igualmente eficaz comer o tempo "refazendo" o resultado de sha256 () quantas vezes forem necessárias para gastar alguns segundos e, em seguida, armazenar a contagem final do loop com o hash para verificar posteriormente uma senha fornecida?

Para o nº 2, é importante usar um sal exclusivo para cada senha. O que não está claro é quão aleatório (ou grande) o sal deve ser. Se o objetivo é evitar que todos que usam "mypassword" como senha tenham o mesmo hash, não basta simplesmente fazer isso ?:

hash = sha256_hex( unique_user_id + user_supplied_password );

ou mesmo isso, embora eu não tenha certeza se me compra alguma coisa:

hash = sha256_hex( sha256( unique_user_id ) + user_supplied_password );

O único benefício que posso ver de usar o ID do usuário, além de eu sei que é único, é evitar ter que salvar o sal junto com o hash. Não é muito de uma vantagem. Existe um problema real em usar o ID de um usuário como o sal? Não cumpre o nº 2?

Suponho que, se alguém puder roubar as senhas com hash do meu usuário, devo assumir que elas podem obter o que quiserem, incluindo o código-fonte que gera o hash. Então, existe algum benefício em adicionar uma string aleatória extra (a mesma string) à senha antes do hashing? Isso é:

# app_wide_string = one-time generated, random 64 7-bit *character* string.
hash = sha256_hex( unique_user_id + app_wide_string + user_supplied_password );

Eu já vi isso sugerido, mas não entendo o que ganho com o sal por usuário. Se alguém quisesse forçar o ataque, eles saberiam que "app_wide_string" e usariam isso quando executassem seu ataque de dicionário, certo?

Existe uma boa razão para usar o bcrypt sobre o meu próprio rolo como descrito acima? Talvez o fato de eu estar fazendo essas perguntas seja motivo suficiente?

BTW - Acabei de cronometrar uma função hash existente que tenho e no meu laptop e posso gerar cerca de 7000 hashes por segundo. Não é exatamente um ou dois segundos que são frequentemente sugeridos.

Alguns links relacionados:

usando sha256 como hashing e salga com ID do usuário

SHA512 vs. Blowfish e Bcrypt

Qual é o comprimento ideal para o sal da senha do usuário?

questionAnswers(2)

yourAnswerToTheQuestion