如何保护 Excel VBA 项目中的 ADO 连接?

How to secure an ADO connection in an Excel VBA project?

我有一个 Excel 电子表格 (.xlsb),它通过 VBA 中的 ActiveX 数据对象 (ADO) 连接到 SQL 服务器,我必须与一群人共享人们。该代码使用以下字符串连接数据库:

' Create the connection string.
sConnString = "Provider=SQLOLEDB;" & _
              "Data Source={server name};" & _
              "Initial Catalog={database name};" & _
              "UserId={username};" & _
              "Password={password};"

如何确保我的 SQL 用户名和密码安全并防止第 3 方访问它们?对 VBA 项目进行密码保护是否足够或者是否可以轻松破解?

VBA密码保护不能被认为是安全的,因为它很容易被绕过。

您当然可以在 VBA 代码中添加某种混淆(散列函数或类似函数),这样密码就不会以纯文本形式显示,但是任何熟悉 VBA 应该可以在短时间内解决这个问题。

我会考虑使用仅包含所需数据的视图来限制对数据库的访问。

隐藏密码可以通过将连接功能放在一个 dll 中来完成,然后您可以在 VBA 代码中引用它。这将需要更多的工作来逆转,并为您提供更多真正隐藏凭据的可能性。另请参阅此回复:

VBA 项目 受到足够的保护 - 任何有 2 小时空闲时间和互联网的人都可能通过。

基本情况是让不同的用户在数据库级别拥有不同的权限。然后要求 Excel 电子表格中的用户在其中一个单元格中或通过用户表单提供密码和用户名。获取密码和用户名并将其用于连接字符串。

作为安全的进一步措施,您可以使用一个小技巧,我称之为 salting。例如。假设给定用户的密码是 vityata。然后要求用户输入它。进入后,获取密码并将其更改为其他内容。这个别的东西应该是数据库的密码。我的意思是这样的:

Public Function str_generator(ByVal str_value As String, ByVal b_fix As Boolean) As String

    Dim l_counter As Long
    Dim l_number As Long
    Dim str_char As String

    On Error GoTo str_generator_Error

    If b_fix Then
        str_value = Left(str_value, Len(str_value) - 1)
        str_value = Right(str_value, Len(str_value) - 1)
    End If

    For l_counter = 1 To Len(str_value)
        str_char = Mid(str_value, l_counter, 1)
        If b_is_odd(l_counter) Then
            l_number = Asc(str_char) + IIf(b_fix, -2, 2)
        Else
            l_number = Asc(str_char) + IIf(b_fix, -3, 3)
        End If

        str_generator = str_generator + Chr(l_number)

    Next l_counter

    If Not b_fix Then
        str_generator = Chr(l_number) & str_generator & Chr(l_number)
    End If

    On Error GoTo 0
    Exit Function

str_generator_Error:

    MsgBox "Error " & Err.Number & " (" & Err.Description & ") in procedure str_generator of Function Modul1"

End Function

Private Function b_is_odd(l_number As Long) As Boolean

    b_is_odd = l_number Mod 2

End Function

假设用户密码是vityata。然后用户输入后,改为cxlv|cwcc,也就是数据库的真实密码

?str_generator("vityata",false)
cxlv|cwcc
?str_generator("cxlv|cwcc",true)
vityata