[sql-server] How to decrypt a password from SQL server?

The SQL Server password hashing algorithm:

hashBytes = 0x0100 | fourByteSalt | SHA1(utf16EncodedPassword+fourByteSalt)

For example, to hash the password "correct horse battery staple". First we generate some random salt:

fourByteSalt = 0x9A664D79;

And then hash the password (encoded in UTF-16) along with the salt:

 SHA1("correct horse battery staple" + 0x9A66D79);
=SHA1(0x63006F007200720065006300740020006200610074007400650072007900200068006F00720073006500200073007400610070006C006500 0x9A66D79)
=0x6EDB2FA35E3B8FAB4DBA2FFB62F5426B67FE54A3

The value stored in the syslogins table is the concatenation of:

[header] + [salt] + [hash]
0x0100 9A664D79 6EDB2FA35E3B8FAB4DBA2FFB62F5426B67FE54A3

Which you can see in SQL Server:

SELECT 
   name, CAST(password AS varbinary(max)) AS PasswordHash
FROM sys.syslogins
WHERE name = 'sa'

name  PasswordHash
====  ======================================================
sa    0x01009A664D796EDB2FA35E3B8FAB4DBA2FFB62F5426B67FE54A3
  • Version header: 0100
  • Salt (four bytes): 9A664D79
  • Hash: 6EDB2FA35E3B8FAB4DBA2FFB62F5426B67FE54A3 (SHA-1 is 20 bytes; 160 bits)

Validation

You validate a password by performing the same hash:

  • grab the salt from the saved PasswordHash: 0x9A664D79

and perform the hash again:

SHA1("correct horse battery staple" + 0x9A66D79);

which will come out to the same hash, and you know the password is correct.

What once was good, but now is weak

The hashing algorithm introduced with SQL Server 7, in 1999, was good for 1999.

  • It is good that the password hash salted.
  • It is good to append the salt to the password, rather than prepend it.

But today it is out-dated. It only runs the hash once, where it should run it a few thousand times, in order to thwart brute-force attacks.

In fact, Microsoft's Baseline Security Analyzer will, as part of it's checks, attempt to bruteforce passwords. If it guesses any, it reports the passwords as weak. And it does get some.

Brute Forcing

To help you test some passwords:

DECLARE @hash varbinary(max)
SET @hash = 0x01009A664D796EDB2FA35E3B8FAB4DBA2FFB62F5426B67FE54A3
--Header: 0x0100
--Salt:   0x9A664D79
--Hash:   0x6EDB2FA35E3B8FAB4DBA2FFB62F5426B67FE54A3

DECLARE @password nvarchar(max)
SET @password = 'password'

SELECT
    @password AS CandidatePassword,
    @hash AS PasswordHash,

    --Header
    0x0100
    +
    --Salt
    CONVERT(VARBINARY(4), SUBSTRING(CONVERT(NVARCHAR(MAX), @hash), 2, 2))
    +
    --SHA1 of Password + Salt
    HASHBYTES('SHA1', @password + SUBSTRING(CONVERT(NVARCHAR(MAX), @hash), 2, 2))

SQL Server 2012 and SHA-512

Starting with SQL Server 2012, Microsoft switched to using SHA-2 512-bit:

hashBytes = 0x0200 | fourByteSalt | SHA512(utf16EncodedPassword+fourByteSalt)

Changing the version prefix to 0x0200:

SELECT 
   name, CAST(password AS varbinary(max)) AS PasswordHash
FROM sys.syslogins

name  PasswordHash
----  --------------------------------
xkcd  0x02006A80BA229556EB280AA7818FAF63A0DA8D6B7B120C6760F0EB0CB5BB320A961B04BD0836 0C0E8CC4C326220501147D6A9ABD2A006B33DEC99FCF1A822393FC66226B7D38
  • Version: 0200 (SHA-2 256-bit)
  • Salt: 6A80BA22
  • Hash (64 bytes): 9556EB280AA7818FAF63A0DA8D6B7B120C6760F0EB0CB5BB320A961B04BD0836 0C0E8CC4C326220501147D6A9ABD2A006B33DEC99FCF1A822393FC66226B7D38

This means we hash the UTF-16 encoded password, with the salt suffix:

  • SHA512("correct horse battery staple"+6A80BA22)
  • SHA512(63006f0072007200650063007400200068006f0072007300650020006200610074007400650072007900200073007400610070006c006500 + 6A80BA22)
  • 9556EB280AA7818FAF63A0DA8D6B7B120C6760F0EB0CB5BB320A961B04BD0836 0C0E8CC4C326220501147D6A9ABD2A006B33DEC99FCF1A822393FC66226B7D38

Examples related to sql-server

Passing multiple values for same variable in stored procedure SQL permissions for roles Count the Number of Tables in a SQL Server Database Visual Studio 2017 does not have Business Intelligence Integration Services/Projects ALTER TABLE DROP COLUMN failed because one or more objects access this column Create Local SQL Server database How to create temp table using Create statement in SQL Server? SQL Query Where Date = Today Minus 7 Days How do I pass a list as a parameter in a stored procedure? SQL Server date format yyyymmdd

Examples related to encryption

mcrypt is deprecated, what is the alternative? Remove 'b' character do in front of a string literal in Python 3 How to resolve the "EVP_DecryptFInal_ex: bad decrypt" during file decryption How to decrypt Hash Password in Laravel RSA encryption and decryption in Python How to fix Invalid AES key length? gpg decryption fails with no secret key error 7-Zip command to create and extract a password-protected ZIP file on Windows? How do I encrypt and decrypt a string in python? AES Encrypt and Decrypt

Examples related to hash

php mysqli_connect: authentication method unknown to the client [caching_sha2_password] What is Hash and Range Primary Key? How to create a laravel hashed password Hashing a file in Python PHP salt and hash SHA256 for login password Append key/value pair to hash with << in Ruby Are there any SHA-256 javascript implementations that are generally considered trustworthy? How do I generate a SALT in Java for Salted-Hash? What does hash do in python? Hashing with SHA1 Algorithm in C#

Examples related to passwords

Your password does not satisfy the current policy requirements Laravel Password & Password_Confirmation Validation Default password of mysql in ubuntu server 16.04 mcrypt is deprecated, what is the alternative? What is the default root pasword for MySQL 5.7 MySQL user DB does not have password columns - Installing MySQL on OSX Changing an AIX password via script? Hide password with "•••••••" in a textField How to create a laravel hashed password Enter export password to generate a P12 certificate