如何使用C#将哈希值存储到SQL Server数据库中?

9
我正在尝试制作一个具有登录/注销功能的网站,并计划正确地进行哈希和加盐处理密码。然而,我面临的问题是如何在数据库中存储密码。我知道需要将哈希+盐处理后的密码存储在数据库中(不能以明文或明文加密方式),但我不知道如何技术上绕过将二进制数据插入到数据库中。
在我的早期尝试中,我唯一能够将数据输入到数据库中的方法是将二进制数据转换为base64字符串并插入到varchar密码字段中,但有些东西告诉我这不是正确的方法。
数据库中的密码字段目前是varchar,但据我所知,哈希密码是二进制的。因此,即使我将密码字段更改为二进制对象,我仍然不知道如何实际插入它!
如果我讲得不清楚,请要求澄清,我会回答你的。

1
哈希可以是varchar类型,完全不必是二进制的,但出于好奇,你正在使用什么哈希函数? - hackartist
1
为什么你不想使用base64?它很简单,而且数据足够小,不必担心大小问题。 - Chris Sainty
Base64是最安全的方式,可以让哈希值以人类可读形式保留。将加盐的哈希值存储为纯文本没有任何问题;这正是存储哈希值而不是密码的整个目的。 - Douglas
好的,我正在使用SHA-512来哈希密码,就像这样:byte[] pwdEntered = pw512.ComputeHash(System.Text.Encoding.Unicode.GetBytes(pwBox.Text));而我放入数据库中的值是这个的结果:Convert.ToBase64String(pwdEntered)。@Chris - 我不是不想使用base64,只是这是我第一次这样做,所以我不确定是否这是可接受的方法,或者是否有其他高级的方法。 - tgmatt
这个问题与认证无关,应该是“如何将二进制数据插入到表中”。 - usr
2个回答

9
在Microsoft SQL Server中,您可以将二进制数据存储在具有binary数据类型的列中(如果需要可变长度数据,则使用varbinary)。您可以将其用于散列和加盐密码。如果您使用512位哈希函数并且还想使用512位盐,则需要2*512/8 = 128字节(例如,binary(128)来存储盐和哈希值)。
通常,无论您使用何种API读写数据库,都应该帮助您读写二进制数据。但是,也许您想使用一些SQL直接将二进制值插入表中。您可以使用以下语法:
insert into MyTable values (0x123456789ABCDEF)

虽然这不是你问题的答案,但如果你在实现自己的密码功能方面遇到困难,可以考虑使用预构建的工业级组件,以避免未来出现尴尬的错误。例如,ASP.NET提供了会员提供程序


7

不,哈希密码并不一定要存储在 varbinary 字段中,您可以对其进行编码并将其存储在 varchar 字段中。Base64 是用于编码任何字符的良好选择。


2
你使用哪种哈希函数可以生成字符串而不是比特序列?我所知道的所有加密哈希函数都会生成一定数量的比特,如128、160、256或512比特,这不是一个字符串(字符串是使用编码存储的)。 - Martin Liversage
@MartinLiversage 我曾经在varchar字段中使用MD5哈希来存储密码,没有出现任何问题。Linux很久以前就在/etc/passwords中使用MD5哈希了。关键是你不必将其存储在varbinary字段中。 - Icarus
1
当然,您可以将哈希存储在varchar列中,但是那样的话,您需要使用类似于base64编码的东西对它们进行编码。您的回答似乎表明哈希可以直接存储,而不考虑在字符串中没有意义的随机二进制序列。 - Martin Liversage
抱歉一直挑剔,但你不能使用UTF-8编码将任何字节序列转换为字符串。尝试使用UTF-8将字节0xC5 0x01转换为字符串,然后再将其转换回字节。由于这些字节不是有效的UTF-8,所以你无法得到原始字节。但Base64可以。 - Martin Liversage
@martinLiversage 恰恰相反,感谢您提供的信息。我不知道这一点。已从答案中删除UTF-8。 - Icarus

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接