加密密码损坏 - 一些保存为加密,一些未加密,一些未保存

时间:2015-03-28 21:16:53

标签: sql-server encryption coldfusion

我正在编写使用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

1 个答案:

答案 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