재우니의 블로그

https://sqlity.net/en/2460/sql-password-hash/

 

Hash Algorithms - How does SQL Server store Passwords? - sqlity.net

How does SQL Server store its own passwords? Discover which hashing algorithm is used and how you can calculate your own password hash value in T-SQL.

sqlity.net

SQL Server 2012 부터 비밀번호는 32 비트 salt 와 함께 SHA_512 해싱 알고리즘 을 사용하여 저장됩니다 .

SHA_512 와 Salt

SQL SERVER 2012 의 패스워드는 32 비트의 salt 와 함께 SHA_512 hashing algorithm 을 사용하여 저장되어 왔습니다. SHA_512 는 12년 동안 사용되어 왔으며, 약간의 노화(ageing)?의 징후를 보여주기 시작했습니다.

모든 SHA 알고리즘은 여러 라운드(rounds) 를 기반으로합니다. 전체 rounds 수 (80)에 대한 성공적인 공격은 없었지만, 깨질 수 있는 라운드(rounds)  수가 증가하고 있습니다. 이제 실제 응용 프로그램에서는 항상 80 라운드를 모두 사용하며, 그렇게 하면 알고리즘이 여전히 안전합니다. 그러나, 깨진 라운드 수가 증가하면 향후 몇 년 내에 중단 될 가능성이 있습니다.

 

해시 값 계산 (Calculating the Hash Value)

hash 값을 계산하는 첫 번째 단계는 비밀번호를 NVARCHAR 에서 VARBINARY 로 변환하는 것 입니다. 이후 SQL Server는 CSPRNG 를 사용하여 32 bit 의 salt를 생성하고 변환 된 암호에 추가합니다. 이 새로운 연결된 VARBINARY 값 중에서 SQL Server는 SHA_512 hash를 계산합니다. 

마지막 단계는 0x0200 salt 및 계산 된 hash 와 함께 연결하여 해시 값을 최종 생성하는 것입니다.

DECLARE @pswd NVARCHAR(MAX) = 'APassword'; 
DECLARE @salt VARBINARY(4) = CRYPT_GEN_RANDOM(4);
DECLARE @hash VARBINARY(MAX); 
SET @hash = 0x0200 + @salt + HASHBYTES('SHA2_512', CAST(@pswd AS VARBINARY(MAX)) + @salt);
SELECT @hash AS HashValue, PWDCOMPARE(@pswd,@hash) AS IsPasswordHash;

PWDCOMPARE 함수  사용하여 결과가 실제로 유효한 SQL Server 암호 hash 임을 확인할 수 있습니다 .

 

MS-SQL 2005

차이점은 SHA_512 대신 SHA1이 사용되며, SQL Server 2005부터 모든 SQL Server 버전에서 실행됩니다.
CRYPT_GEN_RANDOM의 기능이 SQL Server 2008 부터 도입되어 NEWID() 를 사용했습니다.

DECLARE @pswd NVARCHAR(MAX); SET @pswd = 'APassword'; 
DECLARE @salt VARBINARY(4); SET @salt = CAST(NEWID() AS VARBINARY(4));
DECLARE @hash VARBINARY(MAX); 
SET @hash = 0x0100 + @salt + 
            HASHBYTES('SHA1', CAST(@pswd AS VARBINARY(MAX)) + @salt);
SELECT @hash AS HashValue, PWDCOMPARE(@pswd,@hash) AS IsPasswordHash;

 

MS-SQL 2000

SHA1 함수를 사용하여 암호를 해시하며, 암호는 대소 문자를 구분하지 않습니다.  실제 해시 값에는 두 가지 해시 버전의 비밀번호가 포함되어 있습니다. 하나는 변경되지 않은 비밀번호 중 하나이고 모두 대문자 버전의 비밀번호입니다.

SET @hash = 0x0100 + @salt + 
            HASHBYTES('SHA1', CAST(@pswd AS VARBINARY(MAX)) + @salt) + 
            HASHBYTES('SHA1', CAST(UPPER(@pswd) AS VARBINARY(MAX)) + @salt);

참고로, SQL 2000 에서 신규 버전으로 업그레이드하면 암호가 손상 될 수 있다고 하니 고려하시고 사용하시길 바랍니다.