web-dev-qa-db-ja.com

HASHBYTES()を使用すると、nvarcharと変数の結果が異なります

サーバー側のハッシュを使用してパスワードを送信し、データベースでPBKDF2を実行して、ハッシュされたパスワードとソルトの組み合わせを保存しています。

nvarchar(max)と同じ値を保持する_@variable_をハッシュすると、HASHBYTES()関数で異なる結果が得られました。

_DECLARE @hash NVARCHAR(MAX) = 'password5baa61e4c9b93f3f0682250b6'

SELECT HASHBYTES('SHA1', 'password5baa61e4c9b93f3f0682250b6') AS NVARCHAR_INPUT, 
       HASHBYTES('SHA1', @hash) AS VARIABLE_INPUT
_

以下を生成します:

_NVARCHAR_INPUT                             | VARIABLE_INPUT
0xA03BEF0E3EC96CC7C413C6646D3FEC6174DA530F | 0x74B55C42E1E0AB5C5CDF10B28567590B240355C3
_

これはSQL Server 2012です。この特定のデータベースはSQL Server Expressを実行しているため、この質問がバージョンにとらわれないかどうかも知りたいです。

5
Nate Anderson

引用符で囲まれた文字列をNVARCHAR(Unicodeとして扱う)にする場合は、Nをプレフィックスとして付ける必要があります。

DECLARE @hash NVARCHAR(MAX) = 'password5baa61e4c9b93f3f0682250b6'

SELECT HASHBYTES('SHA1', N'password5baa61e4c9b93f3f0682250b6') AS NVARCHAR_INPUT, 
       HASHBYTES('SHA1', @hash) AS VARIABLE_INPUT

これにより、一致するハッシュが表示されます。

NVARCHAR_INPUT                               |VARIABLE_INPUT
0xCF01AF0DCECF41BA0106A264666544C2590A4660   |0xCF01AF0DCECF41BA0106A264666544C2590A4660

プレフィックスはNVARCHARとして宣言され、文字列が変換されるため、ここでは不要です。

DECLARE @hash NVARCHAR(MAX) = 'password5baa61e4c9b93f3f0682250b6'

私はそれでいくつかの問題に遭遇したので、私は通常それを明確にします:

DECLARE @hash NVARCHAR(MAX) = N'password5baa61e4c9b93f3f0682250b6'

ハッシュが異なる理由を説明したい場合は、次の例から始めてください。

DECLARE @n NVARCHAR(1) = N'N'
DECLARE @v VARCHAR(1) = 'N'

SELECT DATALENGTH(@n), DATALENGTH(@v)
12
Erik Darling