MS Access SQL 服务器始终加密参数化
MS Access SQL Server Always Encrypted Parameterization
我正在评估 SQL Server 2016 Always Encrypted 是否可以与我支持的现有 MS Access 2010 应用程序一起使用。
这是我当前的障碍:
我的应用程序调用许多 SQL 需要参数的服务器存储过程。我使用以下函数进行这些调用:
Public Function ExecuteSPWithParamsQuery(poQDFStub As DAO.QueryDef, psParameterString As String) As DAO.Recordset
'-------------------------------------------------------------------------------------------------
' Purpose : Execute an SQL pass-through query that calls a stored procedures requiring parameters.
'
' Params : poQDFStub: pass through query with name of SPROC
' : psParameterString : one or more parameters to be appended to poQDFStub
'
' Returns : Dao.Recordset(dbOpenSnapshot)
'-------------------------------------------------------------------------------------------------
'
If G_HANDLE_ERRORS Then On Error GoTo ErrorHandler
Dim rstResult As DAO.Recordset
'db interface
Dim dbs As DAO.Database: Set dbs = CurrentDb
Dim qdfResult As DAO.QueryDef: Set qdfResult = dbs.CreateQueryDef(vbNullString)
'setup pass through
With qdfResult
.Connect = poQDFStub.Connect
.SQL = poQDFStub.SQL & " " & psParameterString
.ODBCTimeout = 0
.ReturnsRecords = True
End With
'setup result
Set rstResult = qdfResult.OpenRecordset(dbOpenSnapshot, dbSQLPassThrough + dbReadOnly + dbFailOnError)
ExitHere:
'housekeeping
On Error Resume Next
'add cleanup here
Set qdfResult = Nothing
Set dbs = Nothing
'exit protocol
On Error GoTo 0
Set ExecuteSPWithParamsQuery = rstResult
Set rstResult = Nothing
Exit Function
ErrorHandler:
Err.Source = "SQLStoredProcedureHelper.ExecuteSPWithParamsQuery"
HandleError
Resume ExitHere
End Function
对该函数的调用现在将包含参数,这些参数是数据库中加密值的明文版本。
发生这种情况时,我收到以下错误。
206 [Microsoft][ODBC SQL Server Driver][SQL Server] Operand type clash: varchar is incompatible > with nvarchar(255) encrypted with (encryption_type = 'DETERMINISTIC', encryption_algorithm_name
= 'AEAD_AES_256_CBC_HMAC_SHA_256', column_encryption_key_name = 'CEK_Auto1',
column_encryption_key_database_name = 'sandbox')
我对 Always Encrypted Parameterization 做了一些调查。它需要两种技术之一
- .NET
- ODBC 13.1 对于 SQL 服务器
由于这是一个 MS Access 应用程序,.NET 不适用。
我安装了 ODBC 13.1,但我猜测我的直通查询绕过了参数化。
这是我的 ODBC 设置:
[ODBC]
DRIVER=ODBC Driver 13 for SQL Server
ColumnEncryption=Enabled
TrustServerCertificate=No
DATABASE=sandbox
WSID=********
APP=Microsoft Office 2010
Trusted_Connection=Yes
SERVER=*********
关于如何解决此问题或 Always Encrypted 是否不适合我的应用程序的任何想法?
我没有直接使用访问权限,但是,您的连接字符串似乎配置不正确。请通过将以下内容附加到您的连接字符串来将 ColumnEncryption 设置为启用
;ColumnEncryption=Enabled
This article 说明如何使用 ODBC 驱动程序始终加密。
我的问题的解决方案是将我的函数从 DAO 转换为 ADO。希望以下代码可以帮助其他人:
Public Function ExecuteSPWithParamsQueryADO(pSPROCName As String, ParamArray pParams() As Variant) As ADODB.RecordSet
'---------------------------------------------------------------------------------------------------------------------
' Purpose : Executes an SQL pass-through query that requires parameters and returns a recordset.
' : Utilizes ADO rather than DAO.
'
' Author : M. Minneman
'
' Params : pSPROCName - (required) name of SPROC to be executed
' : pParams - (required) one or more parameters required by SPROC
'
' Returns : ADODB.Recordset - ResultSet
'
' Contract : Dependencies
' : G_HANDLE_ERRORS - Global Boolean Constant
' : ImprovedErrorHandler.HandleError - Global error handler
' : ADODB - Microsoft AcitveX Data Objects Library
' : ADO_CONNECT_STRING - valid connect string
' : GeneralFunctions.doCloseAndRelease - CCL Function for cleaning up DAO objects
' :
' : Assumptions (routine may still work, but produce unexpected results)
' : pParams has one index that is 0-based
' :
' : Pre Conditions (must be true before execution)
' : pSPROCName - SPROC exists in ADODB.Connection
' :
' : Post Conditions (should be true after execution)
' : ADODB.Recordset has 0 to many records
' :
'---------------------------------------------------------------------------------------------------------------------
'
' Change Log:
'
' Date By Comment
' 03/17/17 M. Minneman created
'
If G_HANDLE_ERRORS Then On Error GoTo ErrorHandler
Dim oReturn As ADODB.RecordSet
'db interface
Dim cnn As New ADODB.Connection
Dim cmd As New ADODB.Command
Dim prm As New ADODB.Parameter
' Set CommandText equal to the stored procedure name.
cmd.CommandText = pSPROCName
cmd.CommandType = adCmdStoredProc
' Connect to the data source.
cnn.Open ADO_CONNECT_STRING
'validate connection
If cnn.State <> adStateOpen Then
Err.Raise vbObjectError, , "ADO Connection failed to open"
End If
'assign connection to command
cmd.ActiveConnection = cnn
'automatically fill in parameter info from stored procedure.
cmd.Parameters.Refresh
'make sure expected parameters and given arguments are equal
If cmd.Parameters.Count <> UBound(pParams) + 2 Then
Err.Raise vbObjectError, , "SPROC '" & pSPROCName & "' expects " & cmd.Parameters.Count & " arguments. " & UBound(pParams) & " provided."
End If
'set the param values.
Dim i As Integer
For i = 1 To cmd.Parameters.Count - 1
cmd(i) = pParams(i - 1)
Next i
'execute SPROC
Set oReturn = cmd.Execute
ExitHere:
'housekeeping - failure okay
On Error Resume Next
'add cleanup here
GeneralFunctions.doCloseAndRelease _
prm, _
cmd, _
cnn
'everything else - failure not okay
On Error GoTo 0
Set ExecuteSPWithParamsQueryADO = oReturn
Exit Function
ErrorHandler:
'local action
'add local actions here
'default action
Select Case Err.Source
Case "CONSUMED"
Call MsgBox("Operation failed!", vbExclamation, "Message")
Case Else
Err.Source = "SQLStoredProcedureHelper.ExecuteSPWithParamsQueryADO"
Select Case Err.Number
Case Else
HandleError , , , True 'rethrow
End Select
End Select
Resume ExitHere
Resume
End Function
我正在评估 SQL Server 2016 Always Encrypted 是否可以与我支持的现有 MS Access 2010 应用程序一起使用。
这是我当前的障碍:
我的应用程序调用许多 SQL 需要参数的服务器存储过程。我使用以下函数进行这些调用:
Public Function ExecuteSPWithParamsQuery(poQDFStub As DAO.QueryDef, psParameterString As String) As DAO.Recordset
'-------------------------------------------------------------------------------------------------
' Purpose : Execute an SQL pass-through query that calls a stored procedures requiring parameters.
'
' Params : poQDFStub: pass through query with name of SPROC
' : psParameterString : one or more parameters to be appended to poQDFStub
'
' Returns : Dao.Recordset(dbOpenSnapshot)
'-------------------------------------------------------------------------------------------------
'
If G_HANDLE_ERRORS Then On Error GoTo ErrorHandler
Dim rstResult As DAO.Recordset
'db interface
Dim dbs As DAO.Database: Set dbs = CurrentDb
Dim qdfResult As DAO.QueryDef: Set qdfResult = dbs.CreateQueryDef(vbNullString)
'setup pass through
With qdfResult
.Connect = poQDFStub.Connect
.SQL = poQDFStub.SQL & " " & psParameterString
.ODBCTimeout = 0
.ReturnsRecords = True
End With
'setup result
Set rstResult = qdfResult.OpenRecordset(dbOpenSnapshot, dbSQLPassThrough + dbReadOnly + dbFailOnError)
ExitHere:
'housekeeping
On Error Resume Next
'add cleanup here
Set qdfResult = Nothing
Set dbs = Nothing
'exit protocol
On Error GoTo 0
Set ExecuteSPWithParamsQuery = rstResult
Set rstResult = Nothing
Exit Function
ErrorHandler:
Err.Source = "SQLStoredProcedureHelper.ExecuteSPWithParamsQuery"
HandleError
Resume ExitHere
End Function
对该函数的调用现在将包含参数,这些参数是数据库中加密值的明文版本。
发生这种情况时,我收到以下错误。
206 [Microsoft][ODBC SQL Server Driver][SQL Server] Operand type clash: varchar is incompatible > with nvarchar(255) encrypted with (encryption_type = 'DETERMINISTIC', encryption_algorithm_name = 'AEAD_AES_256_CBC_HMAC_SHA_256', column_encryption_key_name = 'CEK_Auto1', column_encryption_key_database_name = 'sandbox')
我对 Always Encrypted Parameterization 做了一些调查。它需要两种技术之一
- .NET
- ODBC 13.1 对于 SQL 服务器
由于这是一个 MS Access 应用程序,.NET 不适用。
我安装了 ODBC 13.1,但我猜测我的直通查询绕过了参数化。
这是我的 ODBC 设置:
[ODBC]
DRIVER=ODBC Driver 13 for SQL Server
ColumnEncryption=Enabled
TrustServerCertificate=No
DATABASE=sandbox
WSID=********
APP=Microsoft Office 2010
Trusted_Connection=Yes
SERVER=*********
关于如何解决此问题或 Always Encrypted 是否不适合我的应用程序的任何想法?
我没有直接使用访问权限,但是,您的连接字符串似乎配置不正确。请通过将以下内容附加到您的连接字符串来将 ColumnEncryption 设置为启用
;ColumnEncryption=Enabled
This article 说明如何使用 ODBC 驱动程序始终加密。
我的问题的解决方案是将我的函数从 DAO 转换为 ADO。希望以下代码可以帮助其他人:
Public Function ExecuteSPWithParamsQueryADO(pSPROCName As String, ParamArray pParams() As Variant) As ADODB.RecordSet
'---------------------------------------------------------------------------------------------------------------------
' Purpose : Executes an SQL pass-through query that requires parameters and returns a recordset.
' : Utilizes ADO rather than DAO.
'
' Author : M. Minneman
'
' Params : pSPROCName - (required) name of SPROC to be executed
' : pParams - (required) one or more parameters required by SPROC
'
' Returns : ADODB.Recordset - ResultSet
'
' Contract : Dependencies
' : G_HANDLE_ERRORS - Global Boolean Constant
' : ImprovedErrorHandler.HandleError - Global error handler
' : ADODB - Microsoft AcitveX Data Objects Library
' : ADO_CONNECT_STRING - valid connect string
' : GeneralFunctions.doCloseAndRelease - CCL Function for cleaning up DAO objects
' :
' : Assumptions (routine may still work, but produce unexpected results)
' : pParams has one index that is 0-based
' :
' : Pre Conditions (must be true before execution)
' : pSPROCName - SPROC exists in ADODB.Connection
' :
' : Post Conditions (should be true after execution)
' : ADODB.Recordset has 0 to many records
' :
'---------------------------------------------------------------------------------------------------------------------
'
' Change Log:
'
' Date By Comment
' 03/17/17 M. Minneman created
'
If G_HANDLE_ERRORS Then On Error GoTo ErrorHandler
Dim oReturn As ADODB.RecordSet
'db interface
Dim cnn As New ADODB.Connection
Dim cmd As New ADODB.Command
Dim prm As New ADODB.Parameter
' Set CommandText equal to the stored procedure name.
cmd.CommandText = pSPROCName
cmd.CommandType = adCmdStoredProc
' Connect to the data source.
cnn.Open ADO_CONNECT_STRING
'validate connection
If cnn.State <> adStateOpen Then
Err.Raise vbObjectError, , "ADO Connection failed to open"
End If
'assign connection to command
cmd.ActiveConnection = cnn
'automatically fill in parameter info from stored procedure.
cmd.Parameters.Refresh
'make sure expected parameters and given arguments are equal
If cmd.Parameters.Count <> UBound(pParams) + 2 Then
Err.Raise vbObjectError, , "SPROC '" & pSPROCName & "' expects " & cmd.Parameters.Count & " arguments. " & UBound(pParams) & " provided."
End If
'set the param values.
Dim i As Integer
For i = 1 To cmd.Parameters.Count - 1
cmd(i) = pParams(i - 1)
Next i
'execute SPROC
Set oReturn = cmd.Execute
ExitHere:
'housekeeping - failure okay
On Error Resume Next
'add cleanup here
GeneralFunctions.doCloseAndRelease _
prm, _
cmd, _
cnn
'everything else - failure not okay
On Error GoTo 0
Set ExecuteSPWithParamsQueryADO = oReturn
Exit Function
ErrorHandler:
'local action
'add local actions here
'default action
Select Case Err.Source
Case "CONSUMED"
Call MsgBox("Operation failed!", vbExclamation, "Message")
Case Else
Err.Source = "SQLStoredProcedureHelper.ExecuteSPWithParamsQueryADO"
Select Case Err.Number
Case Else
HandleError , , , True 'rethrow
End Select
End Select
Resume ExitHere
Resume
End Function