我维护着一个经典的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应用程序的Anon授权设置为“应用程序池标识”。
3)使用以下连接字符串:
cnn = "Provider=MSDASQL;" _
& "Extended Properties=""Driver={ODBC Driver 17 for SQL Server};" _
& "SERVER=***; UID=***; PWD=***;" _
& "DATABASE=***;ColumnEncryption=Enabled;"" "
答案 0 :(得分:4)
SQL Server的新Microsoft OleDb提供程序(MSOLEDBSQL)目前不支持AlwaysEncrypted。您必须使用ODBC,这意味着OleDb提供程序应该是Microsoft ODBC的Microsoft OleDb提供程序(MSDASQL)。因此,您可以使用Microsoft®ODBC Driver 17 for 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中的列加密向导运行,该向导为当前用户存储证书:
然后列出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
。
因此发现列主键的键路径
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下运行。
这是一个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>