/// <summary> /// Erzeugt die Eingabe für BCrypt mit Hilfe des SHA-3 Algorithmus aus eingegebenen Passwort und geladenem Pepper /// </summary> /// <param name="password">Der variable Wert für den Hash</param> /// <param name="pepper">Der geladene Pepper-Wert</param> /// <returns>Der SHA-3 Hash, welcher als Eingabe für BCrypt dient.</returns> private static string SHA3Pepper(string password, string pepper) { var bytes = new ASCIIEncoding().GetBytes(string.Concat(password, pepper)); var crypto = new SHA3Managed(256); var hash = crypto.ComputeHash(bytes); return BitConverter.ToString(hash).Replace("-", "").ToLower(); }
static void Main(string[] arguments) { string input = "The quick brown fox jumps over the lazy dog"; var hash = new SHA3Managed(); byte[] output = hash.ComputeHash(Encoding.UTF8.GetBytes(input)); }
/// <summary> /// Gera um Hash para o valor em texto puro e retorna um resultado /// base64. Antes o hash é calculado, um salt aleatório é gerado e adicionado o texto puro. Este salt /// é armazenado no fim do valor do hash gerado, então pode ser usado depois para verificações. /// </summary> /// <param name="senha"> /// A senha em texto puro que será converida em hash. Este método não verifica /// se o parâmetro é nulo. /// </param> /// <param name="algoritmoHash"> /// Nome do algoritmo do hash. Até o momento, temos: "MD5", "SHA1", /// "SHA256", "SHA384", "SHA512" e "SHA3" (Se outro valor diferente destes /// o hashing do MD5 será utilizado). Estes valores são case insensitive. /// </param> /// <param name="salt"> /// Bytes para o Salt hash. Este parâmetro pode ser nulo, neste caso um salt gerado aleatóriamnte /// será gerado /// </param> /// <returns> /// Valor de hash formatado como uma string base64. /// </returns> public static string GeraValorHash(String senha, String algoritmoHash, Byte[] salt) { // Se o salt não é informado, gera um na hora. if (salt == null) { //define o valor máximo e o mínino de salts // Define min and max salt sizes. int tamanhoMinSalt = 1; int tamanhoMaxSalt = TAMANHO_BYTE_SALT; //Gera um número aleatório para o tamaho do salt Random random = new Random(); int tamanhoSalt = random.Next(tamanhoMinSalt, tamanhoMaxSalt); //Aloca o array de byte, que armzena o salta. salt = new byte[tamanhoSalt]; //Inicia o gerado de números aleatórios. //RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider(); using (RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider()) { //Preenche o hash do salt de forma criptográfica forte. rng.GetNonZeroBytes(salt); } } //Converte a senha em texto puro dentro do array de bytes. byte[] TextoPuroBytes = Encoding.UTF8.GetBytes(senha); //Aloca o array, que armazena o texto puro e o salt. byte[] textoPuroComBytesSalt = new byte[TextoPuroBytes.Length + salt.Length]; //Copia os bytes em texto puro dentro do array resultante. for (int i = 0; i < TextoPuroBytes.Length; i++) textoPuroComBytesSalt[i] = TextoPuroBytes[i]; //anexa os bytes do hash salt para o array resultante. for (int i = 0; i < salt.Length; i++) textoPuroComBytesSalt[TextoPuroBytes.Length + i] = salt[i]; //Como este método pode suportar multiplos algoritmos de hash, precisamos definir //os objetos de hashing com uma classe (abstrata) comum. HashAlgorithm hash; //Faz com que o algoritmo de geração do hash seja informado if (algoritmoHash == null) algoritmoHash = String.Empty; //Inicializa a criação do hash de senha com o algoritmo selecionado switch (algoritmoHash.ToUpper(CultureInfo.CurrentCulture)) { case "SHA1": using (hash = new SHA1Managed()) break; case "SHA256": using (hash = new SHA256Managed()) break; case "SHA384": using (hash = new SHA384Managed()) break; case "SHA512": using (hash = new SHA512Managed()) break; case "SHA3": using (hash = new SHA3Managed(512)) break; default: using (hash = new MD5CryptoServiceProvider()) break; } //Calcula o valor do hash baseado em nossa senha em texto puro com o salt anexado. byte[] hashBytes = hash.ComputeHash(textoPuroComBytesSalt); //Cria um array que armazena o hash e os bytes Salts originais byte[] hashWithSaltBytes = new byte[hashBytes.Length + salt.Length]; //Copia os bytes hash dentro do array resultante; for (int i = 0; i < hashBytes.Length; i++) hashWithSaltBytes[i] = hashBytes[i]; //Anexa bytes salta para o resultado for (int i = 0; i < salt.Length; i++) hashWithSaltBytes[hashBytes.Length + i] = salt[i]; //Converte o resultaado dentro de uma string base64. string hashValue = Convert.ToBase64String(hashWithSaltBytes); //Retorna o resultado. return hashValue; }