我正在编写使用2008 SQL Server数据库的旧版ColdFusion应用程序。我对SQL Server数据库的设置方式知之甚少,但我希望如果我分享一些症状,可能会有人建议检查什么。
数据库使用对称密钥来保护用户密码。我有一个用户名,密码等用户表作为字段。密码已加密。
数据库中的大多数旧版用户都能正常工作。用户可以使用网站登录,更改密码等,没有问题。对于用于测试的记录,我在SQL Server中使用SQL更改了密码,而不是通过网站:“update users set password =”fluffy“where userID in(6543,7654,8765)”等。
当我这样做时,会发生一些事情:
我第一次使用USERID 6543时无法登录网站 和PASSWORD“蓬松” - 但它总是第二次起作用。
当我运行我的存储过程exec get_user_unencrypt_by_id 6543
时,
结果返回“NULL”作为密码。
当我运行查询select * from Users
时,我看到了预期的结果
大多数密码字段中的符号/乱码,但对于用户
6543,7654和8765,我看到“蓬松”。
当我运行查询select * from users where password is null
时,我得到了
没有结果。
我尝试解决问题的方法:
我运行以下SQL来打开并重置主密钥:
OPEN MASTER KEY DECRYPTION BY PASSWORD = ''
ALTER MASTER KEY ADD ENCRYPTION BY SERVICE MASTER KEY
Close Master Key
GO
这似乎没有效果。
我尝试使用SQL
更新损坏的密码 update users set password = EncryptByKey(Key_GUID('PASS_Key_01'), 'fluffy')
where userID in (6543, 7654, 8765)"
当我尝试这个时,这些用户在使用密码'蓬松'时被锁定了。
我已尝试通过网站重置密码。这似乎仅适用于密码未损坏的记录。如果我使用其中一个损坏的密码执行此操作,它似乎暂时有效,但稍后(第二天),密码再次损坏。
名为get_user_unencrypt_by_id
的我的SP就是这样:
OPEN SYMMETRIC KEY PASS_Key_01
DECRYPTION BY CERTIFICATE UserPasswords0324
SELECT userid, username, CONVERT (nvarchar,
DecryptByKey([password])) as 'password', [role], firstname, lastname,
Add1, Add2, City, [State], Zip, Phone, Fax,
FROM users
我不确定还有什么可以尝试,所以我很乐意提出任何建议或想法。感谢。
编辑添加更多细节。在继续调查中,我了解到桌面上有一个触发器。这是触发器。
/****** Object: Trigger [dbo].[encrypt_password_on_update]
Script Date: 4/1/2015 8:55:44 AM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER TRIGGER [dbo].[encrypt_password_on_update]
ON [dbo].[USERS]
after update
AS
BEGIN
/***The purpose of this trigger is to encrypt a password that was
update by the user. When the update statement updates the password,
this encrypts it before storing it in the db***/
DECLARE @updatecount int
DECLARE @userid int
DECLARE @password nvarchar(50)
DECLARE @temp_encryt_password nvarchar(50)
select @updatecount = (select count(userid) from inserted)
if (@updatecount = '1')
BEGIN
SELECT @userid = (SELECT userid FROM Inserted)
OPEN SYMMETRIC KEY PASS_Key_01
DECRYPTION BY CERTIFICATE UserPasswords0324
if (@userid != '' and @userid is not null)
BEGIN
select @temp_encryt_password = (select
EncryptByKey(Key_GUID('PASS_Key_01'), [password]) from users where
userid = @userid)
/***If the password is already encrypted (if the update was for something else other than the password) we don't want to reencrypt***/
if ( CONVERT (nvarchar, DecryptByKey(@temp_encryt_password)) is not null)
BEGIN
update USERS
set [password] = EncryptByKey(Key_GUID('PASS_Key_01'), [password])
where userid = @userid
END
END
END
END
GO
答案 0 :(得分:1)
我相信我已经解决了自己的问题。问题发生在我使用像
这样的查询在数据库中直接重置的密码中update users set password = "fluffy" where userID in (6543, 7654, 8765)
然后,实际加密密码的触发器会查找单个记录:
select @updatecount = (select count(userid) from inserted)
if (@updatecount = '1')
BEGIN
...
因此,密码本身存储在数据库中,并且从未加密,因为我同时更新了多个记录。
然后,当用户尝试登录该站点时,身份验证将失败 - 返回解密密码的SP将返回NULL。该失败将触发用户数据库的更新,以增加失败的登录尝试次数。该查询将触发密码加密,并且第二次用户尝试登录时,身份验证将起作用。因此,出于测试目的,我需要的关键是使用以下一系列查询重置数据库中的密码:
update users set password = "fluffy" where userID = 6543
GO
update users set password = "fluffy" where userID = 7654
GO
update users set password = "fluffy" where userID = 8765
GO