2012-05-15 48 views
6

Necesito saber cuál es la forma más común de almacenar una cadena de conexión del servidor SQL para una aplicación WinForms en VB.NET.¿Cómo almacenar de forma segura una cadena de conexión en una aplicación WinForms?

He buscado en la red y he encontrado respuestas a cada una de las siguientes preguntas:

  • ¿Cómo se leen los valores de app.config
  • Como hacerlo en ASP.NET Referencia: this SO question.
  • ¿Cómo almacenar una cadena de conexión (sin cifrar por lo tanto inseguros)

Me gustaría una respuesta completa sobre cómo almacenar una cadena de conexión en VB.NET en app.config (o settings.settings si es mejor) de forma segura.

¿Es app.config el lugar correcto? ¿Puedo encriptar estos valores?

Respuesta

9

Simplemente, el marco .NET le permite hacer eso, ve

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

Información relevante:

Esto va en el machine.config archivo:

<configProtectedData defaultProvider="RsaProtectedConfigurationProvider"> 
    <providers> 
    <add name="RsaProtectedConfigurationProvider" 
     type="System.Configuration.RsaProtectedConfigurationProvider, ... /> 
    <add name="DataProtectionConfigurationProvider" 
     type="System.Configuration.DpapiProtectedConfigurationProvider, ... /> 
    </providers> 
</configProtectedData> 

Y este es el código de la aplicación:

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 

ACTUALIZACIÓN 1

Gracias @wpcoder, por this link

+0

Creo que sí, gracias. – MarioDS

+1

Dado que esta pregunta tiene muchas vistas, edité su respuesta para asegurarme de que la información no se pierda en caso de que el enlace se rompa. – MarioDS

+1

@pylover _Esto responde a la pregunta pero no proporciona una solución adecuada_. Desde el enlace MS provisto; la ** nota dice **: 'La cadena de conexión solo se puede descifrar en la computadora en la que se cifró'. El [enlace de MS actualizado para el artículo podría proporcionar la solución] (https://docs.microsoft.com/en-us/dotnet/framework/data/adonet/protecting-connection-information) – wpcoder

5

En mi trabajo, almacenamos las cadenas de conexión completas en el app.config, pero las encriptamos con AES256. Funciona bastante bien y agrega una buena cantidad de seguridad. Escribimos una pequeña herramienta que le permite encriptar y desencriptar cadenas de conexión, por lo que editar archivos app.config es bastante fácil. Solo tenemos la clave de encriptación codificada en la aplicación, por lo que si alguien se preocupó de descompilar los ensamblajes, podría resolverlo, pero eleva la barra lo suficientemente alto para nuestras necesidades. Aquí está la clase que utilizamos para cifrar y descifrar las cadenas de conexión:

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 

En realidad, envuelto que en el interior de una clase ConnectionStringEncrpyter cuales hardcodes la clave secreta.

+0

Eso suena muy bien, pero me puede decir cómo codificar ella? Tengo una clase de encriptación lista para contraseñas solamente, no para cadenas de conexión enteras (sobrecarga) – MarioDS

+0

@MarioDeSchaepmeester Agregué un código de ejemplo. Entiendo, la encriptación puede ser un problema. Lo codificamos en base64 para que se almacene bien en el archivo de texto. –

+0

Gracias por la ayuda, pero creo que Pylover me proporcionó la respuesta que estaba buscando. – MarioDS

Cuestiones relacionadas