在 sql 服务器中将 Varbinary 数据转换为 Nvarchar
Converting Varbinary Data to Nvarchar in sql server
我想加密我之前保存密码的密码字段,我的table结构是:
Create table #table (username varchar(50),passwords nvarchar(1000))
Insert into #table values ('abc','pass_123')
现在我正在加密我的密码,如下所示:
update #table set passwords = ENCRYPTBYPASSPHRASE('Key',passwords)
where PATINDEX('%[a0-z9]%',passwords) > 0
但是当我用下面的代码解密密码时:
Select username,convert(varchar(max),DECRYPTBYPASSPHRASE('Key',passwords)) as pwd from #table
它给我的输出是
username Passwords
abc p
如果我像这样更改上面的代码:
Select username,convert(nvarchar(max),DECRYPTBYPASSPHRASE('Key',passwords)) as pwd from #table
它给了我正确的输出
username Passwords
abc pass_123
将 varchar 更改为 nvarchar 后,密码已经存在,但如果有新用户,我在插入期间加密密码,如下所示:
Insert into #table values ('abc',ENCRYPTBYPASSPHRASE('Key','123'))
因此,在使用 nvarchar 解密记录时,我的数据如下所示:
Select username,convert(nvarchar(1000),DECRYPTBYPASSPHRASE('Key',passwords)) as pwd from #table
username pwd
abc pass_123
abc ㈱3
如果我使用 varchar,我的数据将如下所示:
Select username,convert(varchar(max),DECRYPTBYPASSPHRASE('Key',passwords)) as pwd from #table
username pwd
abc p
abc 123
所以基本上,如果我们更新现有记录,则 nvarchar 可用于解密,但如果我们插入新记录,则 varchar 可用于解密。那么我需要做些什么才能通过 varchar 或 nvarchar
获得一致的数据
在您的第一个示例中,您正在从 table 的 NVARCHAR 字段中读取数据。即使您插入的字符串是 VARCHAR,SQL 服务器也会为您转换它。
然而,这是两种不同的数据类型(一种是每个字符两个字节,另一种是单字节),因此会变成不同的二进制文件。
函数ENCRYPTBYPASSPHRASE
和DECRYPTBYPASSPHRASE
将任何有效的文本输入作为有效输入。在您的第一个示例中,您将 VARCHAR 字符串插入 table,将其转换为 NVARCHAR。然后将其用作输入(现在是 NVARCHAR)。但是,如果您直接插入字符串,则将其表示为 VARCHAR,从而将其转换为这种格式的二进制文件。
您当前的 table 结构:
Insert into #table values ('abc','pass_123')
--Values inserted gets converted to NVARCHAR, even though the string 'pass_123' is VARCHAR
update #table set passwords = ENCRYPTBYPASSPHRASE('Key',passwords)
where PATINDEX('%[a0-z9]%',passwords) > 0
--Thus when calling the update the source string is in NVARCHAR encoding
Select username,convert(nvarchar(max),DECRYPTBYPASSPHRASE('Key',passwords)) as pwd from #table
--So the varbinary is based on the NVARCHAR encoding and thus only viewable when it's made nvarchar
/* This is the same as */
Insert into #table values ('abc',ENCRYPTBYPASSPHRASE('Key',N'123'))
--Value being provided as a parameter to ENCRYPTBYPASSPHRASE is already in NVARCHAR format
Select username,convert(nvarchar(1000),DECRYPTBYPASSPHRASE('Key',passwords)) as pwd from #table
--This ends up with the same result, because the varbinary was based on a NVARCHAR
这完全是因为您的源数据类型,在一种情况下,您将 NVARCHAR 作为源,而在另一种情况下,您将 VARCHAR 作为源。转换后为 varbinary 提供不同的值。
MSDN:
从安全的角度来看,这是否是正确的方法是完全不同的问题。
我想加密我之前保存密码的密码字段,我的table结构是:
Create table #table (username varchar(50),passwords nvarchar(1000))
Insert into #table values ('abc','pass_123')
现在我正在加密我的密码,如下所示:
update #table set passwords = ENCRYPTBYPASSPHRASE('Key',passwords)
where PATINDEX('%[a0-z9]%',passwords) > 0
但是当我用下面的代码解密密码时:
Select username,convert(varchar(max),DECRYPTBYPASSPHRASE('Key',passwords)) as pwd from #table
它给我的输出是
username Passwords
abc p
如果我像这样更改上面的代码:
Select username,convert(nvarchar(max),DECRYPTBYPASSPHRASE('Key',passwords)) as pwd from #table
它给了我正确的输出
username Passwords
abc pass_123
将 varchar 更改为 nvarchar 后,密码已经存在,但如果有新用户,我在插入期间加密密码,如下所示:
Insert into #table values ('abc',ENCRYPTBYPASSPHRASE('Key','123'))
因此,在使用 nvarchar 解密记录时,我的数据如下所示:
Select username,convert(nvarchar(1000),DECRYPTBYPASSPHRASE('Key',passwords)) as pwd from #table
username pwd
abc pass_123
abc ㈱3
如果我使用 varchar,我的数据将如下所示:
Select username,convert(varchar(max),DECRYPTBYPASSPHRASE('Key',passwords)) as pwd from #table
username pwd
abc p
abc 123
所以基本上,如果我们更新现有记录,则 nvarchar 可用于解密,但如果我们插入新记录,则 varchar 可用于解密。那么我需要做些什么才能通过 varchar 或 nvarchar
获得一致的数据在您的第一个示例中,您正在从 table 的 NVARCHAR 字段中读取数据。即使您插入的字符串是 VARCHAR,SQL 服务器也会为您转换它。
然而,这是两种不同的数据类型(一种是每个字符两个字节,另一种是单字节),因此会变成不同的二进制文件。
函数ENCRYPTBYPASSPHRASE
和DECRYPTBYPASSPHRASE
将任何有效的文本输入作为有效输入。在您的第一个示例中,您将 VARCHAR 字符串插入 table,将其转换为 NVARCHAR。然后将其用作输入(现在是 NVARCHAR)。但是,如果您直接插入字符串,则将其表示为 VARCHAR,从而将其转换为这种格式的二进制文件。
您当前的 table 结构:
Insert into #table values ('abc','pass_123')
--Values inserted gets converted to NVARCHAR, even though the string 'pass_123' is VARCHAR
update #table set passwords = ENCRYPTBYPASSPHRASE('Key',passwords)
where PATINDEX('%[a0-z9]%',passwords) > 0
--Thus when calling the update the source string is in NVARCHAR encoding
Select username,convert(nvarchar(max),DECRYPTBYPASSPHRASE('Key',passwords)) as pwd from #table
--So the varbinary is based on the NVARCHAR encoding and thus only viewable when it's made nvarchar
/* This is the same as */
Insert into #table values ('abc',ENCRYPTBYPASSPHRASE('Key',N'123'))
--Value being provided as a parameter to ENCRYPTBYPASSPHRASE is already in NVARCHAR format
Select username,convert(nvarchar(1000),DECRYPTBYPASSPHRASE('Key',passwords)) as pwd from #table
--This ends up with the same result, because the varbinary was based on a NVARCHAR
这完全是因为您的源数据类型,在一种情况下,您将 NVARCHAR 作为源,而在另一种情况下,您将 VARCHAR 作为源。转换后为 varbinary 提供不同的值。
MSDN:
从安全的角度来看,这是否是正确的方法是完全不同的问题。