Алгоритм хеширования паролей 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 будет пытаться подобрать пароли. Если он догадывается, он сообщает пароли как ненадежные. И это действительно получается.
Грубое форсирование
Чтобы помочь вам проверить пароли:
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 перешла на использование 512-битного алгоритма SHA-2:
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
(SHA-2 256-бит)
- Соль:
6A80BA22
- Хеш (64 байта):
9556EB280AA7818FAF63A0DA8D6B7B120C6760F0EB0CB5BB320A961B04BD0836 0C0E8CC4C326220501147D6A9ABD2A006B33DEC99FCF1A822393FC66226B7D38
Это означает, что мы хэшируем пароль в кодировке UTF-16 с суффиксом соли:
- SHA512 ("правильная скоба для лошадиных аккумуляторов" +
6A80BA22
)
- SHA512 (
63006f0072007200650063007400200068006f0072007300650020006200610074007400650072007900200073007400610070006c006500
+ 6A80BA22
)
9556EB280AA7818FAF63A0DA8D6B7B120C6760F0EB0CB5BB320A961B04BD0836 0C0E8CC4C326220501147D6A9ABD2A006B33DEC99FCF1A822393FC66226B7D38
person
Ian Boyd
schedule
09.08.2013