使用对称密钥加密时,无法获得经典的ASP参数化查询

时间:2016-11-22 14:06:16

标签: vbscript asp-classic heidisql

我在数据库上设置了密钥和证书设置,我可以在使用HeidiSQL直接输入查询时加密。但我遇到的问题是使用经典的asp来实现这一点。 我已经设置了一个简单的测试表,其中包含一个自动增量标识列和一个用于保存加密数据的var binary max列。

这是我的代码:

chtest.commandtext="OPEN SYMMETRIC KEY SymmetricKey DECRYPTION BY CERTIFICATE [Certificate];"

set rschtest = chtest.execute

chtest.commandtext="INSERT into thetable(thevalue) values(?)"

chtest.Parameters.Append chtest.CreateParameter ("@thevalue", adVarBinary, adParamInput,8000, "EncryptByKey(Key_GUID('SymmetricKey'), 'some text here')"  )

set rschtest = chtest.execute

这似乎可以在二进制数据输入到表中时起作用,但是当直接在服务器上解密时,它只显示“无效”。

直接在服务器上执行这些查询确实有效,例如:

OPEN SYMMETRIC KEY SymmetricKey DECRYPTION BY CERTIFICATE Certificate
INSERT INTO thetable (thevalue) VALUES (EncryptByKey(Key_GUID('SymmetricKey'), 'some text here'))

然后......

OPEN SYMMETRIC KEY SymmetricKey DECRYPTION BY CERTIFICATE [Certificate]
SELECT CONVERT(varchar, DecryptByKey(thevalue)) AS thevalue FROM thetable

工作并显示正确的解密值。

我认为使用经典asp方法时的问题与必须将加密字符串作为varchar插入varbinary有关吗?或类似的东西。

另外,如果我不使用参数化查询,那么一切正常,但显然我想使用准备好的查询来保证安全。

请注意,这是一个遗留应用程序,所以我必须使用经典的asp。

任何帮助表示感谢。

1 个答案:

答案 0 :(得分:1)

ADODB.Command电话没有意义的时刻,您需要对.CreateParameter()进行一些重组。您应该始终通过参数传递值的基本数据类型之后的任何操作(在本例中为EncryptByKey()应该在CommandText定义的查询内完成。

Dim sql: sql = ""

sql = sql & "OPEN SYMMETRIC KEY SymmetricKey DECRYPTION BY CERTIFICATE [Certificate]" & vbCrLf
sql = sql & "INSERT INTO thetable (thevalue) VALUES (EncryptByKey(Key_GUID('SymmetricKey'), ?))"

With chtest
  .ActiveConnection = your_connection_string
  .CommandText = sql
  .CommandType = adCmdText
  Call .Parameters.Append(.CreateParameter("@thevalue", adVarChar, adParamInput, 8000, "some text here")

  'As you are doing an INSERT use adExecuteNoRecords to cut down on processing 
  'and improve performance.
  Set rschtest = chtest.Execute(, , adExecuteNoRecords)
End With

你会注意到我已经改变

.CreateParameter ("@thevalue", adVarBinary, adParamInput,8000, "EncryptByKey(Key_GUID('SymmetricKey'), 'some text here')"  )

.CreateParameter("@thevalue", adVarChar, adParamInput, 8000, "some text here")

这是因为在这种情况下操作基值时,字符串'some text here'的任何操作都需要在传递基值之外完成。 这就是.CommandText现在包含EncryptByKey(Key_GUID('SymmetricKey'), ?)的原因,因此在执行期间只通过Parameter集合传递基值。