Home » Looking into SQL Server 2025’s new PBKDF2 hashing algorithm

Looking into SQL Server 2025’s new PBKDF2 hashing algorithm

by Vlad Drumea
0 comments

In this post I explore the impact of SQL Server 2025’s PBKDF2 hashing algorithm on password cracking and compare it with SQL Server 2022.

Spoiler: SQL Server 2025’s PBKDF2 hashing algorithm turns 45 seconds worth of password brute-forcing into an estimated 154008 seconds.

Intro

I’ve written previously about auditing or cracking SQL Server login passwords either online (inside the instance itself) or offline (exporting the hashes and using a specialized cracking tool).

Last week, Microsoft’s Pieter Vanhove published a blog post that covers What’s new in SQL Server 2025 security.

The thing that caught my attention was the point about RFC2898, also known as a password-based key derivation function (PBKDF), being introduced as a default for SQL logins in SQL Server 2025.

As per the blog post, the algorithm still uses SHA-512 but hashes the password multiple times (100,000 iterations), significantly slowing down brute-force attacks.

This applies to:

  • CREATE LOGIN WITH PASSWORD
  • CREATE USER WITH PASSWORD
  • CREATE APPLICATION ROLE

So, naturally, I was curious about how this might impact attempts to crack SQL login password hashes online.

How the new hash looks

I’m creating the following SQL login on a SQL Server 2025 instance as well as a 2022 instance:


Then I run the following query to get the name and the password hash of the newly created login:



Note that the “header” of the hash is 0x0300, which indicates that this hash is version 3.
Meaning that it uses SQL Server 2025’s new PBKDF2 hashing algorithm.

For reference, SQL Server 2012-2022 SQL login hashes start with 0x0200, indicating version 2 of SQL Server’s hashing algorithm.
And the password hash was constructed as 0x0200+Salt+SHA-512(password + Salt).
Where the salt was a random 4 byte hexadecimal number, like what CRYPT_GEN_RANDOM(4) would return.

How to generate one

While I don’t yet have way to build the new PBKDF2 password hash from parts, the PWDENCRYPT function can be used to hash a clear text password.


Comparing cracking duration

Single login

All the instances involved have identical configuration (MAXDOP 4, CTP 50, Max Memory MB 4096).
The VM based instances are on a Windows Server 2025 VM with 4 CPU cores and 12GB of RAM.
While the container based instances are on a QNAP NAS with 4/8 CPU cores/threads and 32GB of RAM.
As for specific versions, the 2022 instances are running 16.0.4195.2, and the 2025 instances are on 17.0.800.3.

I’ve create the same test_login SQL login on all instance involved in this test.


And then I use PWDCOMPARE with time statistics to see how long it takes to hash the clear text string and compare it to the login’s hash for both the correct password and an incorrect password.


The result looks like this, with 1 meaning that the clear text password matches the existing password hash.


And the time statistics output in the messages tab looks like this on the 2022 instance:

SQL Server parse and compile time:
CPU time = 7 ms, elapsed time = 7 ms.

(1 row affected)

SQL Server Execution Times:
CPU time = 0 ms, elapsed time = 0 ms.

(1 row affected)

SQL Server Execution Times:
CPU time = 0 ms, elapsed time = 0 ms.

Ignore the parse and compile time since that’s just the time SQL Server takes to parse the T-SQL and compile the plan, not the actual duration of PWDCOMPARE.

InstanceElapsed time (ms) – correct password Elapsed time (ms) – incorrect password
2022 VM00
2025 VM147149
2022 Container00
2025 Container152150

It looks like the PBKDF2 hashing algorithm used in SQL Server 2025 does incur some additional time.
Around 150 milliseconds in this case.
Which makes sense since it’s an iterative algorithm and hashes the password 100,000 times in an attempt to make brute-force attacks even slower and less feasible* than they are now.

*If you’re using passwords that aren’t like Summer2025 or [CompanyName][Year].

Multiple logins with generated password list

For this, I’ll try to do something similar to an actual audit/online cracking.

Since the number of generated candidates will be fairly large, I’ll only create a few logins (besides sa, and test_login).
I’ll also create a new database for a login that will have its password derived from the database name.


This means that with sa, test_login and the newly created logins, there are 6 SQL logins on each instance.

And then I use my QuickSQLPassAudit.sql script with the following options:


Execute it on the target instances and take note of the Duration value specified in the Messages tab.
This excludes the time needed to generate the password candidates, and only accounts for the actual password “cracking”.

Here’s how the result looks for one of the 2022 instances:

SSMS result set showing the password identified for 4 of the existing 6 sql logins SQL Server 2025 PBKDF2 password hash

Note that neither sa nor test_login show up here since they both have strong passwords that are beyond the scope of this script.

The results

So… here’s the deal: after executing in a decent amount of time on both the 2022 instances, when the time came to run it on the 2025 instances I cancelled the execution around the 60 minutes mark.

But I do have an average duration of 150 milliseconds per password candidate from the previous (single login) test.
I also know that the current execution of the QuickSQLPassAudit.sql script generates 171121 password candidates for each instance.
So, I should be able to estimate the number of seconds this would take to compare the 171121 password candidates against the password hashes of the 6 logins using the new PBKDF2 algorithm.


So, for 6 logins, with 171121 password candidates at 150 milliseconds per candidate, it would take 154008.90 seconds or 42.8 hours.

The side-by-side comparison:

InstanceDuration (seconds)
2022 VM45
2025 VM154008.90 (estimated)
2022 Container71
2025 Container154008.90 (estimated)

Note that the duration for the 2022 instance running in a container is higher, so using the same estimate for its 2025 counterpart as for the VM may be a bit optimistic.

But SQL Server 2025’s new hashing algorithm makes password brute-forcing way less feasible than it was before.

Does throwing more CPU at it help?

Not really.

As far as I can tell, the hashing process is single-threaded.
And I can’t imagine it working if it would be multi-threaded since it’s iterative and the next hash is built “on top” of the previous one in a loop that spans 100k iterations.

The portion of the script that checks password candidates against the password hashes ends up also being single-threaded (due to the hashing) and row by row, because that’s what you generally get when you join on a function.

I’ve doubled the CPU core count on my VM and increased MAXDOP accordingly on the 2025 instance.
But the average PWDCOMPARE time still hovers in the 150 milliseconds area.

This is an obstacle which external tools such as hashcat can help overcome, since they can split password candidates and/or hashes across multiple threads.
Speaking of password cracking tools…

Can SQL Server 2025’s new PBKDF2 hashes be cracked offline?

Nope. At least not at the moment.
The current version of hashcat only supports the previous versions of SQL Server hashing algorithms, and the same goes for John The Ripper (which kinda feels like abandonware at this point).

Can PBKDF2 be used in SQL Server 2022?

Yes, it can. As long as you’re running SQL Server 2022 CU12 or newer and you’re ok with enabling a trace flag.
Read more about it here and make sure you take note of the caveats if you might need to revert.

Can a login hash migrated from SQL Server 2022 work in SQL Server 2025?

A while ago I wrote a blog post about migrating sa’s password hash, from one instance to another, without knowing the clear text password.

For this test, I’ll use a modified version of the query from that post to target the test_login login on the SQL Server 2022 instance.


Note the 0x0200 header indicating that this is a pre-2025 hash.

I execute the resulting T-SQL in the SQL Server 2025 instance, and it doesn’t error out, so that’s a first good sign.

Let’s see how PWDCOMPARE handles it:


That’s a yes, it’s able to match the clear text password with the hash even if the hash is for a previous version of SQL Server.

Does authentication still work?

While still connected as sa, I grant the following permission to test_login so that it’s able to view the contents of the password_hash column:

I connect via sqlcmd as test_login and run the following query:


Well, that’s interesting. It looks like test_login’s password hash was updated to the last version during login.

But just to confirm this and show you that there’s nothing up my sleeve, I reset the hash to the 2022 one, and re-check what happens.

I use a little trick to be able to reconnect as test_login as soon as I disconnect from my connection as sa:


Once the connection as sa is established, I paste the following code all in one go:


This does the following:

  • Sets column widths to something that’s more human-friendly.
  • Returns information about my current login, as well as details about test_login.
  • Exits the first sqlcmd connection (the one using sa).
  • At this point, the sqlcmd connection as test_login will be established due to chaining the two sqlcmd commands with a semicolon.
  • Checks the same information as the first query.

Notice how the password hash version changes between the two connections (arrow 1).
And test_login’s password hash is updates as soon as the connection is initiated, judging by the 27 milliseconds difference between the modify_date timestamp and the now one (arrow 2).

So, SQL Server 2012-2022 password hashes can be migrated to SQL Server 2025 without issues, but they are updated to SQL Server 2025’s PBKDF2 hashing algorithm at the first successful authentication.

I’m guessing that this process was actually implemented in case of an in-place upgrade from 20022 or 2019 to 2025.
Where all the old password hashes will be updated as soon as the pre-upgrade logins will authenticate to the upgraded instance.

Conclusion

SQL Server 2025’s new PBKDF2 hashing algorithm improves security by increasing the time needed for brute-force attacks against the password hashes.

I’m really curios to see if hashcat will be updated to support the new hashing algorithm, since offline cracking tends to be way more efficient and use more/specialized resources.

Keep in mind that this isn’t the same as a login brute-force attack where a user just tries various passwords for a login from SSMS/sqlcmd or any other client/script.

You may also like

Leave a Comment

* By using this form you agree with the storage and handling of your data by this website.

This site uses Akismet to reduce spam. Learn how your comment data is processed.