Reputation: 39
I want to change a password, in a stored procedure from NVARCHAR into its MD5 hash, but after executing it the password hash is shown as Chinese characters. Why?
I am using this code EncryptByPassPhrase('MD5', @Password)
but it still shows the result as Chinese characters
BEGIN
DECLARE @HashThis nvarchar(4000);
SELECT @HashThis = CONVERT(nvarchar(4000),@Password);
Insert Into tblUserLogin (ICNumber,Email,[Password],CreateBy,CreateDate,LastUpdateBy,LastUpdateDate)
Values (@ICNumber,@Email,HASHBYTES('SHA1',@HashThis),@FirstName,GETDATE(),@FirstName,GETDATE())
END
The Expected Result should like this:
0x01000000E6A0E10AF0144E38670D9B8E92E6E22787F9CD27B467E253
But the Actual Result is:
詫鸺쇬⒍맣㮶뎨뗮兴サ
Upvotes: 4
Views: 3746
Reputation: 45779
This is because you're storing the result of calling the HASHBYTES
function into an NVARCHAR
field when you should store it in a VARBINARY
.
Here's a worked example that shows this:
CREATE TABLE UserHash
(
[Password_NVARCHAR] NVARCHAR(200),
[Password_VARBINARY] VARBINARY(20)
)
DECLARE @Password NVARCHAR(20) = 'Abcdefghijklmnop'
DECLARE @HashThis nvarchar(4000);
SELECT @HashThis = CONVERT(nvarchar(4000),@Password);
INSERT
INTO [UserHash]
(
Password_NVARCHAR,
Password_VARBINARY
)
SELECT HASHBYTES('SHA1',@HashThis),
HASHBYTES('SHA1',@HashThis)
SELECT *
FROM [UserHash]
Here's the result of the last statement in that code:
As you can see, the NVARCHAR
version shows something you're not expecting which is because the result of calling HASHBYTES
is being interpreted as text, rather than as a series of bytes.
If you look at the length of the text in the Password_NVARCHAR
field (e.g. by executing SELECT LEN(Password_NVARCHAR) FROM [UserHash]
) you'll see this returned as 10. As NVARCHAR
stores text using 2 bytes per character, your 20 byte hash is being displayed as a 10 character string.
NOTE: In the script above I've sized Password_VARBINARY
to fit an SHA1 result, as per the linked documentation for HASHBYTES
you should size the column according to the hashing algorithm being used:
The output conforms to the algorithm standard: 128 bits (16 bytes) for MD2, MD4, and MD5; 160 bits (20 bytes) for SHA and SHA1; 256 bits (32 bytes) for SHA2_256, and 512 bits (64 bytes) for SHA2_512
ASIDE: Don't store a password as a hash, use a Salted Hash.
Upvotes: 3