In our system we are hashing passwords with the following method.
public static string HashPassword(string password, byte[] salt)
{
if (salt == null)
{
throw new ArgumentNullException($"{nameof(salt)}");
}
var pbkdf2 = new Rfc2898DeriveBytes(
password,
salt,
Iterations,
HashingAlgorithm
);
byte[] hash = pbkdf2.GetBytes(KeySize);
return $"{Convert.ToBase64String(salt)}{SaltEndMarker}{Convert.ToBase64String(hash)}";
}
For maintenance reasons, we want to set initial hash in the database. As this is a complex algorithm, I thought to use a SQL CLR function, instead of implementing the algorithm directly in SQL. The SQL CLR function approach works, but in comparison to the pure .NET App, is slower in the order of 2-3 magnitudes.
I did some experiments by changing the number of iterations, 1000 takes less than 1 sec, 10K takes 7 sec and 100K 70 sec.
Does anyone have an explanation why the SQL CLR function vs pure .NER App difference? How can it be sped up?
Edited:
- SQL server version: Microsoft SQL Server 2019
- I know that the number of iterations should be greater than 10K. I tried with different values to see how the execution time changes.
I thought to use SQL CLR functionwhy? It's not faster and worse, you've weakened security by transmitting a cleartext password to the database. You also cause issues to the database server as any transactions that involve this function will get blocked waiting for a response. And the memory used will be taken from the database's memorythis is a complex algorithm,not really, you already usedRfc2898DeriveBytes. Password hashing is meant to be slow anyway, that's what protects against brute force. Nowadays the minimum iterations are 10K, not 1000. As forwhyyou didn't explain which SQL Server version you use, but it will be slower than the current .NET (Core) versions. SQLCLR isn't used because it's faster, it's used to create functionality that can be used in queries, like creating new types, new aggregations and, if it makes sense, new functions.PBKDF2 with HMAC-SHA512, 128-bit salt, 256-bit subkey, 100000 iterations.. Such calculations don't belong to the DBSQLCLR_QUANTUM_PUNISHMENTwaits dba.stackexchange.com/questions/164891/…varbinary, and why you are storing the salt in the same blob as the hash.