sql-server - 如何从经典 ASP 读取 SQL Always-加密列

标签 sql-server asp-classic always-encrypted

我维护一个经典的 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;"" "

最佳答案

新的 Microsoft OleDb Provider for SQL Server (MSOLEDBSQL) 不支持 AlwaysEncrypted(当前)。您必须使用 ODBC,这意味着 OleDb 提供程序应该是 Microsoft OleDb Provider for ODBC (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 中的列加密向导,该向导为当前用户存储证书:

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 应用程序池帐户的用户证书存储中。 。请注意,所有用户的证书相对路径必须相同。如果您最初将其配置为存储在用户的证书存储中,则无法将其存储在 IIS 盒子上的计算机存储中。 SQL Server 存储 key 的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>

关于sql-server - 如何从经典 ASP 读取 SQL Always-加密列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55736446/

相关文章:

sql-server - 如何备份 SQL Server 2008 上的所有数据库

javascript - 如何使用查询字符串 ASP 获取 #

asp-classic - 如何在 ASP 中引发 "File Download"并防止热链接

azure - 未知的外部数据源类型 - 始终加密

sql - varchar 与使用 (encryption_type = 'DETERMINISTIC' 加密) 的 varchar(50) 不兼容

asp.net - 始终使用 Asp.net 身份加密

sql-server - 更新 SQL Server 索引键列后缺少行

php - Mac 上的 Sqlsrv 扩展

sql - 优化对不相关表的大量插入

javascript - 如果在 Sharepoint 设计器上勾选了复选框,如何显示 div?