SQL Server-lösenordshashingalgoritmen:
hashBytes = 0x0100 | fourByteSalt | SHA1(utf16EncodedPassword+fourByteSalt)
Till exempel för att hasha lösenordet "korrekt hästbatterihäftning" . Först genererar vi lite slumpmässigt salt:
fourByteSalt = 0x9A664D79;
Och hasha sedan lösenordet (kodat i UTF-16) tillsammans med saltet:
SHA1("correct horse battery staple" + 0x9A66D79);
=SHA1(0x63006F007200720065006300740020006200610074007400650072007900200068006F00720073006500200073007400610070006C006500 0x9A66D79)
=0x6EDB2FA35E3B8FAB4DBA2FFB62F5426B67FE54A3
Värdet som lagras i syslogins
tabellen är sammanlänkningen av:
[header] + [salt] + [hash]
0x0100
9A664D79
6EDB2FA35E3B8FAB4DBA2FFB62F5426B67FE54A3
Som du kan se i SQL Server:
SELECT
name, CAST(password AS varbinary(max)) AS PasswordHash
FROM sys.syslogins
WHERE name = 'sa'
name PasswordHash
==== ======================================================
sa 0x01009A664D796EDB2FA35E3B8FAB4DBA2FFB62F5426B67FE54A3
- Versionshuvud:
0100
- Salt (fyra byte):
9A664D79
- Hash:
6EDB2FA35E3B8FAB4DBA2FFB62F5426B67FE54A3
(SHA-1 är 20 byte; 160 bitar)
Validering
Du validerar ett lösenord genom att utföra samma hash:
- ta saltet från den sparade
PasswordHash
:0x9A664D79
och utför hashen igen:
SHA1("correct horse battery staple" + 0x9A66D79);
som kommer ut till samma hash, och du vet att lösenordet är korrekt.
Det som en gång var bra, men nu är svagt
Hashingalgoritmen som introducerades med SQL Server 7 1999 var bra för 1999.
- Det är bra att lösenordet hash saltat.
- Det är bra att lägga till saltet till lösenordet, i stället för att lägga in Det.
Men idag är det förlegat. Den kör bara hashen en gång, där den borde köra den några tusen gånger, för att motverka brute-force-attacker.
Faktum är att Microsofts Baseline Security Analyzer kommer, som en del av sina kontroller, att försöka bruteforce lösenord. Om den gissar något, rapporterar den lösenorden som svaga. Och det blir en del.
Brute Forcing
För att hjälpa dig testa några lösenord:
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 och SHA-512
Från och med SQL Server 2012 gick Microsoft över till att använda SHA-2 512-bitar:
hashBytes = 0x0200 | fourByteSalt | SHA512(utf16EncodedPassword+fourByteSalt)
Ändra versionsprefixet till 0x0200
:
SELECT
name, CAST(password AS varbinary(max)) AS PasswordHash
FROM sys.syslogins
name PasswordHash
---- --------------------------------
xkcd 0x02006A80BA229556EB280AA7818FAF63A0DA8D6B7B120C6760F0EB0CB5BB320A961B04BD0836 0C0E8CC4C326220501147D6A9ABD2A006B33DEC99FCF1A822393FC66226B7D38
- Version:
0200
(SHA-2 256-bitars) - Salt:
6A80BA22
- Hash (64 byte):
9556EB280AA7818FAF63A0DA8D6B7B120C6760F0EB0CB5BB320A961B04BD0836 0C0E8CC4C326220501147D6A92BFC7A92BFC7A92BFC7A9A92FFC7A9A92BFC7A9A92B23D6A92BFC3A9A92B2D3A9A92B2D3A9A92D2C32622205011147D6A92FFC2A9A92F23A9A92F3Fcode
Det betyder att vi hash det UTF-16-kodade lösenordet, med saltsuffixet:
- SHA512("korrekt hästbatterihäftning" +
6A80BA22
) - SHA512(
63006f0072007200650063007400200068006f007200730065002000620061007400740065007200790001kod07c +
6A80BA22
) 9556EB280AA7818FAF63A0DA8D6B7B120C6760F0EB0CB5BB320A961B04BD0836 0C0E8CC4C326220501147D6A9ABD2A006B232Akod63FC2A006B332Akod63FC2A006B321C236F2A0096B331Akod