如何从经典ASP中读取SQL Always-encrypted列

问题描述 投票:4回答:1

我维护一个经典的ASP应用程序(是的,我知道,我们正在努力)并且需要在SQL 2017中访问Always Encrypted列。

我已经导入了证书并在SSMS和PowerShell中进行了测试。我在ASP中能做的最好的事情是将加密值作为字节数组。我尝试了比我记忆中更多的连接字符串组合。我的ASP开发盒是Windows 10;数据服务器是SQL 2017。

cnn = "Provider=MSOLEDBSQL; DataTypeCompatibility=80; " _
    & "DRIVER={ODBC Driver 17 for SQL Server}; " _
    & "SERVER=xxxx; UID=xxxxx; PWD=xxxxx; DATABASE=xxxx; " _
    & "ColumnEncryption=Enabled; Column Encryption Setting=Enabled;"
Set oDB = CreateObject( "ADODB.Connection" )
oDB.Open cnn
set oCmd = Server.CreateObject("ADODB.Command") 
oCmd.ActiveConnection = cnn
oCmd.CommandText = "SELECT top 10 ID, Enc FROM tbl1"
set rst = oCmd.Execute()

代码无错误地工作,但加密列(Enc,varchar(50))作为字节数组返回。当我得到纯文本值时,我似乎得到了加密值。我也试过用相同的结果调用存储过程。查询中没有过滤器,因此无需参数化。任何想法接下来要尝试什么?


回答: 1)将证书导入与该Web应用程序的AppPool标识相同的用户。 2)将Web应用程序的匿名授权设置为应用程序池标识。 3)使用此连接字符串:

  cnn = "Provider=MSDASQL;" _
      & "Extended Properties=""Driver={ODBC Driver 17 for SQL Server};" _
      & "SERVER=***; UID=***; PWD=***;" _
      & "DATABASE=***;ColumnEncryption=Enabled;"" "
sql-server asp-classic always-encrypted
1个回答
4
投票

新的Microsoft OleDb Provider for SQL Server(MSOLEDBSQL)不支持AlwaysEncrypted(当前)。您必须使用ODBC,这意味着OleDb提供程序应该是Microsoft OleDb ODBC(MSDASQL)提供程序。因此,您可以使用Microsoft®ODBCDriver 17为SQL Server配置系统DSN,其连接字符串如下:

cnn = "Provider=MSDASQL;DSN=testdb;"

或者将所有ODBC驱动程序参数嵌入到MSDASQL连接字符串的“扩展属性”中。喜欢

cnn = "Provider=MSDASQL;Extended Properties=""Driver={ODBC Driver 17 for SQL Server};Server=localhost;Database=testdb;Trusted_Connection=yes;ColumnEncryption=Enabled;"" "

这是演练,在使用ASP进行测试之前使用第一个VBScript进行测试。

从...开始:

create database testdb
go
use testdb

create table tbl1(id int, Enc varchar(200))

insert into tbl1(id,enc) values (1,'Hello')

然后在运行SSMS的计算机上运行SSMS中的列加密向导,该向导为当前用户存储证书:

gif of the Column Encryption Wizard

然后是query.vbs的列表:

cnn = "Provider=MSDASQL;Extended Properties=""Driver={ODBC Driver 17 for SQL Server};Server=localhost;Database=testdb;Trusted_Connection=yes;ColumnEncryption=Enabled;"" "
Set oDB = CreateObject( "ADODB.Connection" )
oDB.Open cnn
set oCmd = CreateObject("ADODB.Command") 
oCmd.ActiveConnection = cnn
oCmd.CommandText = "SELECT top 10 ID, Enc FROM tbl1"
set rst = oCmd.Execute()
rst.MoveFirst()
msgbox( cstr(rst("Enc")) )

哪个可以从命令行运行:

cscript  .\query.vbs

要从ASP执行此操作,您还必须根据文档here将证书放在IIS App Pool帐户的用户证书存储中。请注意,证书的相对路径必须对所有用户都相同。如果最初将其配置为存储在用户的证书存储中,则无法将其存储在IIS框中的计算机存储中。 SQL Server存储密钥的key_path,并指示客户端在哪里找到证书,例如CurrentUser/my/388FF64065A96DCF0858D84A88E1ADB5A927DECE

因此,发现Column Master Key的关键路径

select name, key_path from sys.column_master_keys

然后从具有它的计算机导出证书:

 PS C:\Windows> $path = "cert:\CurrentUser\My\388FF64065A96DCF0858D84A88E1ADB5A927DECE"
 PS C:\Windows> $mypwd = ConvertTo-SecureString -String "xxxxxxx" -Force -AsPlainText
 PS C:\Windows> Export-PfxCertificate -Cert $path -FilePath c:\temp\myexport.pfx -ChainOption EndEntityCertOnly  -Password $mypwd

在IIS服务器上作为应用程序池标识用户运行,导入它

PS C:\WINDOWS> $mypwd = ConvertTo-SecureString -String "xxxxxxx" -Force -AsPlainText
PS C:\WINDOWS> Import-PfxCertificate -FilePath C:\temp\myexport.pfx -CertStoreLocation Cert:\LocalMachine\My -Password $mypwd

如果您正在使用匿名/表单身份验证,请确保您已将IIS匿名身份验证配置为在应用程序池标识下运行,而不是默认的IUSR。

IIS Anonymous Authentication Edit Dialog

这是一个要测试的ASP页面:

<!DOCTYPE html>
<html>
<body>

<p>Output :</p>

<%

Set objNetwork = CreateObject("Wscript.Network")
Response.write("The current user is " & objNetwork.UserName)

cnn = "Provider=MSDASQL;Extended Properties=""Driver={ODBC Driver 17 for SQL Server};Server=localhost;Database=testdb;Trusted_Connection=yes;ColumnEncryption=Enabled;"" "
Set oDB = CreateObject( "ADODB.Connection" )
oDB.Open cnn
set oCmd = CreateObject("ADODB.Command") 
oCmd.ActiveConnection = cnn
oCmd.CommandText = "SELECT top 10 ID, Enc FROM tbl1"
set rst = oCmd.Execute()
rst.MoveFirst()
Response.write(cstr(rst("Enc")) )

%>

</body>
</html>
© www.soinside.com 2019 - 2024. All rights reserved.