2024年1月16日火曜日

(PC) SQL-Server ハッシュ値によるパスワード管理について

SQL-Server 2022ですが、よくあるログイン等で、ユーザー様が入力してくれたパスワードをどのように管理(データベースに登録)しておくかという話です。

暗号化まではしないパターン。

ハッシュ値に変換する事によって、パッとみて平文じゃなかったら良いじゃないか、というポリシーで良い時の話です。


ハッシュ値を使ったパスワード管理の考え方



-- -------------------------------------------
--ハッシュ値を使ったパスワード管理方法
-- -------------------------------------------

-- --------------------------
-- 管理側の準備
-- --------------------------


--パスワードとソルトを宣言する
DECLARE @dbPass NVARCHAR(MAX) = 'testpass1234567890';
DECLARE @dbSalt VARBINARY(MAX) = CRYPT_GEN_RANDOM(32);

--パスワードとソルトを結合して、パスワードのハッシュ値を求める
DECLARE @dbHash VARBINARY(MAX) = HASHBYTES('SHA2_256', @dbPass + CAST(@dbSalt AS NVARCHAR(50)));

--[データベース登録のつもり]ハッシュ値とソルトを仮にデータベースに登録したとする。
IF OBJECT_ID('tempdb.dbo.#dbData','U') IS NOT NULL BEGIN DROP TABLE #dbData; END;
SELECT @dbHash AS HASH
      ,@dbSalt AS SALT
  INTO #dbData;

-- --------------------------
-- 利用側
-- --------------------------
--ユーザーが画面からパスワード入力としたとする。
DECLARE @userPass NVARCHAR(MAX) = 'testpass1234567890';--OKとなるパスワード


-- --------------------------
-- 検査側
-- --------------------------
--検査
DECLARE @userSalt VARBINARY(MAX) = (SELECT SALT FROM #dbData);

DECLARE @userHash VARBINARY(MAX) = HASHBYTES('SHA2_256',@userPass + CAST(@userSalt AS NVARCHAR(50)));

IF @userHash != @dbHash
BEGIN
    print '(NG)パスワードは間違っています!!';
END
ELSE BEGIN
    print '(OK)';
END;

-- --------------------------
-- 特記事項
-- --------------------------
-- CONVERT(NVARCHAR(MAX),値,2)という具合に、文字列変換パラメーターに2を付けると、
-- バイナリの先頭から0xを省いた文字列に出来ます。
SELECT HASH
      ,SALT
      ,CONVERT(NVARCHAR(MAX),HASH,2) AS STRING_HASH --0x除外の文字列
      ,CONVERT(NVARCHAR(MAX),SALT,2) AS STRING_SALT --0x除外の文字列
  FROM #dbData