我们的一个合作伙伴正在调用一个包含名为 token 的参数的 Web 服务。令牌是两个数字的 MD5 哈希的结果,并帮助我们使用我们的合作伙伴系统验证用户。我们的合作伙伴向用户询问两个字符串,将它们连接起来,通过 MD5 运行它们,然后调用我们的 Web 服务。MD5的结果就是token,以字符串的形式提交给我们。
我们将有效令牌存储在数据库中——因为我们使用 SQL Server 来计算我们端的令牌,SQL 似乎最乐意将令牌存储为 varbinary,这是 MD5 计算的本机结果。
我们有两段代码试图做同样的事情——运行一个选择查询,根据提交的令牌提取一个值。一个使用动态查询(这是一个问题),但它有效。另一个尝试以参数化(更安全)的方式做同样的事情,它不起作用 - 它无法找到令牌。
这是两个相互竞争的尝试。首先,失败的参数化版本:
byteArrayToken = System.Text.UnicodeEncoding.Unicode.GetBytes(stringToken)
scSelectThing.CommandText = "select thing from tokenstable where token=@token"
Dim param As SqlParameter = scSelectThing.Parameters.Add("@token", SqlDbType.VarBinary)
param.Value = byteArrayToken
lbOutput2.Text = scSelectThing.ExecuteScalar()
其次,有效的动态查询字符串版本:
Dim scSelectThing As New SqlCommand
scSelectThing.CommandText = "select thing from tokenstable where token=convert(varbinary, " + stringToken + " )"
lbOutput2.Text = scSelectThing.ExecuteScalar()
当我们运行 SQL 分析器时,这实际上是对 DB 执行的:
exec sp_executesql N'select thing from tokenstable where token=@token',N'@token varbinary(68)',@token=0x3000780046003800380034004100450036003400430038003300440033004100380034003800460046004300380038004200390034003400330043004200370042004600
这对我来说看起来不对,看起来好像我们正在做的事情会导致堆栈中的某些东西在某处进行错误的转换。
有什么想法吗?在其中使用动态查询启动显然是不可接受的。
编辑:
该字符串是一个 MD5 哈希结果。为了让它在查询分析器中工作,我们这样做:
select * from tokenstable where
token=convert(varbinary, 0xF664AE32C83D3A848FFC88B9443CB7BF )
请注意缺少引号,如果我们引用它,查询将失败。我们要比较的字段是 varbinary,SQL Server 已将我们端的 MD5 计算结果存储在其中。