【问题标题】:MS Access SQL Server Always Encrypted ParameterizationMS Access SQL Server 始终加密参数化
【发布时间】:2017-08-06 04:37:40
【问题描述】:

我正在评估 SQL Server 2016 Always Encrypted 是否可以与我支持的现有 MS Access 2010 应用程序一起使用。

这是我目前的障碍:

我的应用程序调用许多需要参数的 SQL Server 存储过程。我使用以下函数进行这些调用:

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] 操作数类型冲突:varchar 不兼容 > 与使用 (encryption_type = 'DETERMINISTIC', encryption_algorithm_name 加密的 nvarchar(255) = 'AEAD_AES_256_CBC_HMAC_SHA_256',column_encryption_key_name = 'CEK_Auto1', column_encryption_key_database_name = '沙盒')

我对始终加密的参数化进行了一些调查。它需要两种技术之一

  • .NET
  • 适用于 SQL Server 的 ODBC 13.1

由于这是一个 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 不适合我的应用程序的任何想法?

【问题讨论】:

    标签: vba ms-access-2010 dao sql-server-2016 always-encrypted


    【解决方案1】:

    我没有直接使用访问权限,但是,似乎您的连接字符串可能没有正确配置。请通过将以下内容附加到您的连接字符串来将 ColumnEncryption 设置为启用

    ;ColumnEncryption=Enabled
    

    This article 解释了如何使用始终加密的 ODBC 驱动程序。

    【讨论】:

      【解决方案2】:

      解决我的问题的方法是将我的函数从 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
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-12-11
        • 2018-03-11
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多