Алгоритм хеширования паролей SQL Server:
hashBytes = 0x0100 | fourByteSalt | SHA1(utf16EncodedPassword+fourByteSalt)
Например, для хэширования пароля "правильный скрепка батареи для лошадей" . Сначала мы генерируем некоторую случайную соль:
fourByteSalt = 0x9A664D79;
А затем хэшируйте пароль (закодированный в UTF-16) вместе с солью:
SHA1("correct horse battery staple" + 0x9A66D79);
=SHA1(0x63006F007200720065006300740020006200610074007400650072007900200068006F00720073006500200073007400610070006C006500 0x9A66D79)
=0x6EDB2FA35E3B8FAB4DBA2FFB62F5426B67FE54A3
Значение, хранящееся в таблице syslogins
, представляет собой конкатенацию:
[заголовок] + [соль] + [хеш]
0x0100
9A664D79
6EDB2FA35E3B8FAB4DBA2FFB62F5426B67FE54A3
Что вы можете увидеть в SQL Server:
SELECT
name, CAST(password AS varbinary(max)) AS PasswordHash
FROM sys.syslogins
WHERE name = 'sa'
name PasswordHash
==== ======================================================
sa 0x01009A664D796EDB2FA35E3B8FAB4DBA2FFB62F5426B67FE54A3
- Заголовок версии:
0100
- Соль (четыре байта):
9A664D79
- Хеш:
6EDB2FA35E3B8FAB4DBA2FFB62F5426B67FE54A3
(SHA-1 составляет 20 байтов; 160 бит)
Проверка
Вы проверяете пароль, выполняя тот же хеш:
- захватите соль из сохраненных
PasswordHash
: 0x9A664D79
и снова выполните хеширование:
SHA1("correct horse battery staple" + 0x9A66D79);
, который получит тот же хеш, и вы знаете, что пароль правильный.
То, что когда-то было хорошо, а сейчас слабо
Алгоритм хеширования, введенный в SQL Server 7 в 1999 году, был хорош для 1999 года.
- Хорошо, что хеш пароля солен.
- Хорошо добавить соль к паролю, а не предварять его.
Но сегодня оно устарело. Он запускает хэш только один раз, где он должен запускать его несколько тысяч раз, чтобы предотвратить атаки методом грубой силы.
Фактически, Microsoft Baseline Security Analyzer, в рамках своих проверок, попытается взломать пароли. Если он угадает, он сообщает, что пароли слабые. И это действительно есть.
Перебор
Чтобы помочь вам проверить некоторые пароли:
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 и SHA-512
Начиная с SQL Server 2012, Microsoft перешла на использование SHA-2 512-бит:
hashBytes = 0x0200 | fourByteSalt | SHA512(utf16EncodedPassword+fourByteSalt)
Изменение префикса версии на 0x0200
:
SELECT
name, CAST(password AS varbinary(max)) AS PasswordHash
FROM sys.syslogins
name PasswordHash
---- --------------------------------
xkcd 0x02006A80BA229556EB280AA7818FAF63A0DA8D6B7B120C6760F0EB0CB5BB320A961B04BD0836 0C0E8CC4C326220501147D6A9ABD2A006B33DEC99FCF1A822393FC66226B7D38
- Версия:
0200
(256-бит SHA-2)
- Соль:
6A80BA22
- Хеш (64 байта):
9556EB280AA7818FAF63A0DA8D6B7B120C6760F0EB0CB5BB320A961B04BD0836 0C0E8CC4C326220501147D6A9ABD2A006B33DEC99FCF1A822393FC66226B7D38
Это означает, что мы хешируем пароль в кодировке UTF-16 с суффиксом соли:
- SHA512 ( "правильная скоба батареи для лошадей" +
6A80BA22
)
- SHA512 (
63006f0072007200650063007400200068006f0072007300650020006200610074007400650072007900200073007400610070006c006500
+ 6A80BA22
)
9556EB280AA7818FAF63A0DA8D6B7B120C6760F0EB0CB5BB320A961B04BD0836 0C0E8CC4C326220501147D6A9ABD2A006B33DEC99FCF1A822393FC66226B7D38