/** * O procedimento é: * - recebe senha X * - Hasheia X com SHA256, resultando em Y * - "Acopla" o nounce (login) no final deste resultado (Y), resultando em Z * - gera um Salt aleatório, com 29 caracteres * - Utiliza o BCrypt para gerar outra hash, sendo esta resultado do Salt + Z, resultando em W * - Como os primeiros 29 caracteres de W são o proprio salt, encripta-se, com o AES, apenas os caracteres que não fazem parte do Salt, resultando Salt + R * - aclopa-se, então, uma Pepper aleatória ao final da string, sendo esta, agora, composta por Salt + R + Pepper; resultando em G * - Por fim, hasheia-se G com SHA512 e adiciona ao início da string o Salt; resultando em Salt+F */ public static string Encrypt(string password, string username) { string hashedPassword = SHA_256.GenerateSHA256String(password); string nounced = hashedPassword + username; string mySalt = BCrypt.GenerateSalt(); string myHash = BCrypt.HashPassword(nounced, mySalt); string result = mySalt + AES256.AES_Encrypt(myHash.Substring(29, myHash.Length - 29)) + Pepper.Generate(); result = mySalt + SHA_512.GenerateSHA512String(result); return(result); }
/** * Como é impossível determinar pela senha salva no banco de dados qual Pepper foi gerada na criação da senha, * esta função gera todas as combinações possiveis (00...AZ...zz); e, então, testa se com alguma delas, o resultado * é igual ao que está salvo no banco de dados. Caso algum dos resultados seja igual ao que está salvo, retorna verdadeiro. * Caso nenhuma delas resulte, a função retorna falso. */ public static bool Check(string password, string hashed, string salt) { for (int i = 0; i < 62; ++i) { for (int j = 0; j < 62; ++j) { int firstArrayIndex = i; int secondArrayIndex = j; string firstDigit = ConvertIndex(firstArrayIndex); string secondDigit = ConvertIndex(secondArrayIndex); string pepper = firstDigit + secondDigit; string aux = password + pepper; string result = salt + SHA_512.GenerateSHA512String(aux); if (result == hashed) { return(true); } } } return(false); }