Eu estava lendo um dos artigos de DavidHayden sobre Hashing User Senhas .
Realmente não consigo o que ele está tentando alcançar.
Aqui está o código dele:
private static string CreateSalt(int size)
{
//Generate a cryptographic random number.
RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider();
byte[] buff = new byte[size];
rng.GetBytes(buff);
// Return a Base64 string representation of the random number.
return Convert.ToBase64String(buff);
}
private static string CreatePasswordHash(string pwd, string salt)
{
string saltAndPwd = String.Concat(pwd, salt);
string hashedPwd =
FormsAuthentication.HashPasswordForStoringInConfigFile(
saltAndPwd, "sha1");
return hashedPwd;
}
Existe algum outro método C # para fazer hash de senhas e adicionar sal a ela?
SHA1
não é de nível criptográfico, então você deve pelo menos usarSHA256
, que gera 256 bits ou 32 bytes. MAS, 256 bits NÃO são facilmente convertíveis na base 64, porque cada caractere base64 codifica 6 bits e 256 não é totalmente divisível por 6. Portanto, você precisa de um denominador comum de 6 (para base64) e 8 (para bits em um byte) mais de 256 bits, ou seja, 264 picadas ou 33 bytes. TLDR: Use 33.Respostas:
Na verdade, isso é meio estranho, com as conversões de strings - que o provedor de associação faz para colocá-las em arquivos de configuração. Hashes e sais são blobs binários, você não precisa convertê-los em strings, a menos que queira colocá-los em arquivos de texto.
No meu livro, Beginning ASP.NET Security , (finalmente, uma desculpa para dar uma olhada no livro), faço o seguinte
A geração de sal é como o exemplo da pergunta. Você pode converter texto em matrizes de bytes usando
Encoding.UTF8.GetBytes(string)
. Se você precisar converter um hash em sua representação de cadeia, poderá usá-loConvert.ToBase64String
eConvert.FromBase64String
convertê-lo novamente.Você deve observar que não pode usar o operador de igualdade em matrizes de bytes, ele verifica as referências e, portanto, basta percorrer as duas matrizes verificando cada byte para
Sempre use um novo sal por senha. Os sais não precisam ser mantidos em segredo e podem ser armazenados ao lado do próprio hash.
fonte
return array1.Length == array2.Length && !array1.Where((t, i) => t != array2[i]).Any();
O que o blowdart disse, mas com um pouco menos de código. Use Linq ou
CopyTo
para concatenar matrizes.O Linq também oferece uma maneira fácil de comparar suas matrizes de bytes.
Antes de implementar isso, no entanto, confira esta postagem . Para hash de senha, convém um algoritmo de hash lento, não rápido.
Para esse fim, há a
Rfc2898DeriveBytes
classe que é lenta (e pode ser mais lenta) e pode responder à segunda parte da pergunta original, na medida em que ela pode pegar uma senha e salt e retornar um hash. Veja esta pergunta para mais informações. Observe que o Stack Exchange está usando oRfc2898DeriveBytes
hash de senha (código-fonte aqui ).fonte
Eu tenho lido que funções de hash como SHA256 não foram realmente destinadas ao uso de senhas de armazenamento: https://patrickmn.com/security/storing-passwords-security/#notpasswordhashes
Em vez disso, funções de derivação de chave adaptáveis como PBKDF2, bcrypt ou scrypt foram. Aqui está um baseado em PBKDF2 que a Microsoft escreveu para PasswordHasher em sua biblioteca Microsoft.AspNet.Identity:
Observe que isso requer o pacote de nuget Microsoft.AspNetCore.Cryptography.KeyDerivation instalado, que requer o .NET Standard 2.0 (.NET 4.6.1 ou superior). Para versões anteriores do .NET, consulte a classe Crypto da biblioteca System.Web.Helpers da Microsoft.
Atualização de novembro de 2015
Resposta atualizada para usar uma implementação de uma biblioteca diferente da Microsoft que usa o hash PBKDF2-HMAC-SHA256 em vez do PBKDF2-HMAC-SHA1 (observe que PBKDF2-HMAC-SHA1 ainda é seguro se iterCount for alto o suficiente). Você pode verificar a origem da qual o código simplificado foi copiado, pois ele lida com a validação e atualização de hashes implementados a partir da resposta anterior, útil se você precisar aumentar o iterCount no futuro.
fonte
PBKDF2SubkeyLength
para 20 bytes. Esse é o tamanho natural de SHA1 e aumentá-lo além do que desacelera o defensor sem desacelerar o atacante. 2) Eu recomendo aumentar a contagem de iterações. Eu recomendo 10.000 a 100.000, dependendo do seu orçamento de desempenho. 3) Uma comparação de tempo constante também não faria mal, mas não tem muito impacto prático.O sal é usado para adicionar um nível extra de complexidade ao hash, para dificultar a trinca por força bruta.
De um artigo no Sitepoint :
Não existe um método para fazer isso automaticamente no .NET, então você terá a solução acima.
fonte
Eu criei uma classe que tem o seguinte método:
Validar entrada
`
fonte
Bah, isso é melhor! http://sourceforge.net/projects/pwdtknet/ e é melhor porque ..... executa o Key Stretching E usa o HMACSHA512 :)
fonte
Criei uma biblioteca SimpleHashing.Net para facilitar o processo de hash com as classes básicas fornecidas pela Microsoft. SHA comum não é realmente suficiente para ter senhas armazenadas com segurança.
A biblioteca usa a ideia do formato hash do Bcrypt, mas como não há implementação oficial do MS, prefiro usar o que está disponível na estrutura (por exemplo, PBKDF2), mas é um pouco difícil de usar.
Este é um exemplo rápido de como usar a biblioteca:
fonte
É assim que faço .. Crio o hash e o armazeno usando a
ProtectedData
API:fonte
Eu li todas as respostas e eu acho que aqueles suficiente, especialmente @ Michael artigos com hashing lento e @CodesInChaos bons comentários, mas eu decidi compartilhar o meu trecho de código para hash / validação de que pode ser útil e não requer [ Microsoft.AspNet.Cryptography .KeyDerivation ].
Por favor, preste atenção à função SlowEquals que é tão importante. Finalmente, espero que ajude e, por favor, não hesite em me aconselhar sobre melhores abordagens.
fonte
Use o
System.Web.Helpers.Crypto
pacote NuGet da Microsoft.Ele adiciona automaticamente sal ao hash.Você hash uma senha como esta:
var hash = Crypto.HashPassword("foo");
Você verifica uma senha como esta:
var verified = Crypto.VerifyHashedPassword(hash, "foo");
fonte
Se você não usa o núcleo asp.net ou .net, também há uma maneira fácil em projetos = = .Net Standard 2.0.
Primeiro, você pode definir o tamanho desejado do número de hash, sal e iteração que está relacionado à duração da geração de hash:
Para gerar a senha e o sal, você pode usar algo como isto:
Para verificar se a senha digitada pelo usuário é válida, verifique os valores em seu banco de dados:
O seguinte teste de unidade mostra o uso:
Microsoft Rfc2898DeriveBytes Origem
fonte
Em resposta a esta parte da pergunta original "Existe algum outro método C # para hash de senhas" Você pode fazer isso usando o ASP.NET Identity v3.0 https://www.nuget.org/packages/Microsoft.AspNet.Identity. EntityFramework / 3.0.0-rc1-final
fonte
fonte
fonte