MS SQL的EncryptByKey是否适合加密登录密码?求代码示例
用ENCRYPTBYKEY加密登录密码的可行性与最佳实践
核心结论:不适合用ENCRYPTBYKEY加密登录密码
ENCRYPTBYKEY是可逆的对称加密函数,设计初衷是处理需要还原明文的敏感数据(如信用卡号、身份证号),但登录密码的安全要求是不可逆存储——我们只需要验证用户输入的密码是否匹配,不需要还原原始密码。用它存密码的风险包括:
- 一旦对称密钥泄露,所有加密的密码都会被解密,直接导致数据泄露;
- 对称密钥的管理复杂度高,增加了系统的安全隐患。
登录密码的正确存储方式
应该使用带盐值的不可逆哈希算法,确保即使数据泄露,攻击者也无法还原明文密码。SQL Server推荐的方案:
- 使用
HASHBYTES函数配合随机盐值:生成唯一的盐值存储,将盐值和密码拼接后哈希,验证时用相同盐值重新哈希对比; - 对于SQL Server 2016及以上,可使用
HASHBYTES('SHA2_512', CONCAT(@Salt, @Password))这类强哈希算法。
ENCRYPTBYKEY加密密码的代码示例(仅作技术演示,禁止用于生产环境)
1. 初始化加密所需的密钥和证书
-- 创建数据库主密钥(仅执行一次) CREATE MASTER KEY ENCRYPTION BY PASSWORD = 'StrongMasterKeyPass@123'; -- 创建保护对称密钥的证书 CREATE CERTIFICATE DemoPasswordCert WITH SUBJECT = 'Demo Certificate for Password Encryption'; -- 创建对称密钥(AES-256算法) CREATE SYMMETRIC KEY DemoPasswordKey WITH ALGORITHM = AES_256 ENCRYPTION BY CERTIFICATE DemoPasswordCert;
2. 加密并存储密码
-- 打开对称密钥 OPEN SYMMETRIC KEY DemoPasswordKey DECRYPTION BY CERTIFICATE DemoPasswordCert; -- 准备明文密码和用户名(用用户名作为验证器,防止篡改) DECLARE @PlainPwd NVARCHAR(100) = 'User@Pass123'; DECLARE @Username NVARCHAR(50) = 'demo_user'; -- 执行加密 DECLARE @EncryptedPwd VARBINARY(MAX) = EncryptByKey( Key_GUID('DemoPasswordKey'), @PlainPwd, 1, -- 启用验证器 CONVERT(VARBINARY(MAX), @Username) ); -- 关闭对称密钥 CLOSE SYMMETRIC KEY DemoPasswordKey; -- 插入到用户表 INSERT INTO dbo.Users (Username, EncryptedPassword) VALUES (@Username, @EncryptedPwd);
3. 解密并验证密码
DECLARE @InputUser NVARCHAR(50) = 'demo_user'; DECLARE @InputPwd NVARCHAR(100) = 'User@Pass123'; -- 打开对称密钥 OPEN SYMMETRIC KEY DemoPasswordKey DECRYPTION BY CERTIFICATE DemoPasswordCert; -- 验证密码是否匹配 SELECT CASE WHEN DecryptByKey(u.EncryptedPassword, 1, CONVERT(VARBINARY(MAX), u.Username)) = CONVERT(VARBINARY(MAX), @InputPwd) THEN '登录成功' ELSE '登录失败' END AS LoginStatus FROM dbo.Users u WHERE u.Username = @InputUser; -- 关闭对称密钥 CLOSE SYMMETRIC KEY DemoPasswordKey;
内容的提问来源于stack exchange,提问作者Narish
相关产品推荐
相关产品推荐

