如何在WinForms应用程序中安全地存储连接字符串?

Mar*_*oDS 8 .net vb.net security encryption connection-string

我需要知道在VB.NET中为WinForms应用程序存储SQL服务器连接字符串的常用方法是什么.

我搜索了网,我找到了以下每个问题的答案:

  • 如何读取app.config值
  • 如何在ASP.NET 参考中做到这一点:这个问题.
  • 如何存储连接字符串(未加密因此不安全)

我想要一个完整的答案,如何安全地存储VB.NET中的连接字符串app.config(或者settings.settings如果它更好).

app.config对的地方吗?我可以加密这些值吗?

pyl*_*ver 11

简单来说,.net框架允许您这样做,请参阅

http://msdn.microsoft.com/en-us/library/89211k9b(v=vs.80).aspx

相关信息:

这进入了machine.config文件:

<configProtectedData defaultProvider="RsaProtectedConfigurationProvider">
  <providers>
    <add name="RsaProtectedConfigurationProvider" 
      type="System.Configuration.RsaProtectedConfigurationProvider, ... />
    <add name="DataProtectionConfigurationProvider" 
      type="System.Configuration.DpapiProtectedConfigurationProvider, ... />
  </providers>
</configProtectedData>
Run Code Online (Sandbox Code Playgroud)

这是应用程序代码:

Shared Sub ToggleConfigEncryption(ByVal exeConfigName As String)
    ' Takes the executable file name without the
    ' .config extension.
    Try
        ' Open the configuration file and retrieve 
        ' the connectionStrings section.
        Dim config As Configuration = ConfigurationManager. _
            OpenExeConfiguration(exeConfigName)

        Dim section As ConnectionStringsSection = DirectCast( _
            config.GetSection("connectionStrings"), _
            ConnectionStringsSection)

        If section.SectionInformation.IsProtected Then
            ' Remove encryption.
            section.SectionInformation.UnprotectSection()
        Else
            ' Encrypt the section.
            section.SectionInformation.ProtectSection( _
              "DataProtectionConfigurationProvider") 'this is an entry in machine.config
        End If

        ' Save the current configuration.
        config.Save()

        Console.WriteLine("Protected={0}", _
        section.SectionInformation.IsProtected)

    Catch ex As Exception
        Console.WriteLine(ex.Message)
    End Try
End Sub
Run Code Online (Sandbox Code Playgroud)

更新1

感谢@wpcoder,获取此链接

  • @pylover _This回答了这个问题,但没有提供适当的解决方案_.从MS链接提供;**说明**:连接字符串只能在加密的计算机上解密.[文章的更新MS链接可以提供解决方案](https://docs.microsoft.com/en-us/dotnet/framework/data/adonet/protecting-connection-information) (3认同)

Ste*_*art 7

在我的工作中,我们将完整的连接字符串存储在app.config中,但我们使用AES256对它们进行加密.它工作得很好,并增加了相当多的安全性.我们编写了一个小工具,允许您加密和解密连接字符串,因此编辑app.config文件非常简单.我们只是在应用程序中对加密密钥进行了硬编码,因此如果有人关心反编译程序集,那么可以解决它,但它会提高我们的需求.这是我们用来加密和解密连接字符串的类:

Public Class Aes256Base64Encrypter
    Public Function Decrypt(ByVal encryptedText As String, ByVal secretKey As String) As String
        Dim plainText As String = Nothing
        Using inputStream As MemoryStream = New MemoryStream(System.Convert.FromBase64String(encryptedText))
            Dim algorithm As RijndaelManaged = getAlgorithm(secretKey)
            Using cryptoStream As CryptoStream = New CryptoStream(inputStream, algorithm.CreateDecryptor(), CryptoStreamMode.Read)
                Dim outputBuffer(0 To CType(inputStream.Length - 1, Integer)) As Byte
                Dim readBytes As Integer = cryptoStream.Read(outputBuffer, 0, CType(inputStream.Length, Integer))
                plainText = Unicode.GetString(outputBuffer, 0, readBytes)
            End Using
        End Using
        Return plainText
    End Function


    Public Function Encrypt(ByVal plainText As String, ByVal secretKey As String) As String
        Dim encryptedPassword As String = Nothing
        Using outputStream As MemoryStream = New MemoryStream()
            Dim algorithm As RijndaelManaged = getAlgorithm(secretKey)
            Using cryptoStream As CryptoStream = New CryptoStream(outputStream, algorithm.CreateEncryptor(), CryptoStreamMode.Write)
                Dim inputBuffer() As Byte = Unicode.GetBytes(plainText)
                cryptoStream.Write(inputBuffer, 0, inputBuffer.Length)
                cryptoStream.FlushFinalBlock()
                encryptedPassword = System.Convert.ToBase64String(outputStream.ToArray())
            End Using
        End Using
        Return encryptedPassword
    End Function


    Private Function getAlgorithm(ByVal secretKey As String) As RijndaelManaged
        Const salt As String = "put a salt key here"
        Const keySize As Integer = 256

        Dim keyBuilder As Rfc2898DeriveBytes = New Rfc2898DeriveBytes(secretKey, Unicode.GetBytes(salt))
        Dim algorithm As RijndaelManaged = New RijndaelManaged()
        algorithm.KeySize = keySize
        algorithm.IV = keyBuilder.GetBytes(CType(algorithm.BlockSize / 8, Integer))
        algorithm.Key = keyBuilder.GetBytes(CType(algorithm.KeySize / 8, Integer))
        algorithm.Padding = PaddingMode.PKCS7
        Return algorithm
    End Function
End Class
Run Code Online (Sandbox Code Playgroud)

实际上,我们将其包装在ConnectionStringEncrpyter类中,该类对密钥进行硬编码.