.net 如何在 WinForms 应用程序中安全地存储连接字符串?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/10606892/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to securely store a connection string in a WinForms application?
提问by MarioDS
I need to know what is the common way to store a SQL server connection string for a WinForms application in VB.NET.
我需要知道在 VB.NET 中为 WinForms 应用程序存储 SQL 服务器连接字符串的常用方法是什么。
I have searched the net and I found answers to each of the following questions:
我搜索了网络,找到了以下每个问题的答案:
- How do I read app.config values
- How to do it in ASP.NET Reference: this SO question.
- How do I store a connection string (unencrypted thus unsafe)
- 我如何读取 app.config 值
- 如何在 ASP.NET参考中做到这一点:this SO question。
- 如何存储连接字符串(未加密因此不安全)
I would like a full answer on how to store a connection string in VB.NET in app.config(or settings.settingsif it's better) securely.
我想要一个关于如何在 VB.NET 中安全地存储连接字符串app.config(或者settings.settings如果它更好)的完整答案。
Is app.configthe right place? Can I encrypt these values?
是app.config正确的地方吗?我可以加密这些值吗?
回答by pylover
Simply , the .net framework allows you to do that , see
简单地说,.net 框架允许您这样做,请参阅
http://msdn.microsoft.com/en-us/library/89211k9b(v=vs.80).aspx
http://msdn.microsoft.com/en-us/library/89211k9b(v=vs.80).aspx
Relevant information:
相关信息:
This goes into the machine.configfile:
这进入machine.config文件:
<configProtectedData defaultProvider="RsaProtectedConfigurationProvider">
<providers>
<add name="RsaProtectedConfigurationProvider"
type="System.Configuration.RsaProtectedConfigurationProvider, ... />
<add name="DataProtectionConfigurationProvider"
type="System.Configuration.DpapiProtectedConfigurationProvider, ... />
</providers>
</configProtectedData>
And this is the application code:
这是应用程序代码:
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
UPDATE 1
更新 1
Thanks @wpcoder, for this link
感谢@wpcoder,提供此链接
回答by Steven Doggart
At my job, we store the full connection strings in the app.config, but we encrypt them with AES256. It works pretty well and adds a fair amount of security. We wrote a little tool that lets you encrypt and decrypt connection strings so editing the app.config files is pretty easy. We just have the encryption key hardcoded in the application, so if anyone cared to decompile the assemblies, the could figure it out, but it raises the bar high enough for our needs. Here's the class we use to encrypt and decrypt the connection strings:
在我的工作中,我们将完整的连接字符串存储在 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
Actually, we wrapped that inside of a ConnectionStringEncrpyter class which hardcodes the secret key.
实际上,我们将其封装在一个 ConnectionStringEncrpyter 类中,该类对密钥进行了硬编码。

