none
string de conexion a DB, la forma más segura RRS feed

  • Pregunta

  • Hola todos,

    Actualmente trabajo con Mysql desde vb.net 2010 una aplicacion windows forms.

    La manera como he venido haciendo mi string de conexion es así:

    Public Class Conexion
        Private servidor, port, database, usuario, password As String
    
        Public Sub New()
            Try
                servidor = ConfigurationManager.AppSettings("servidor").ToString
                database = ConfigurationManager.AppSettings("database").ToString
                usuario = ConfigurationManager.AppSettings("usuario").ToString
                port = ConfigurationManager.AppSettings("port").ToString
                password = ConfigurationManager.AppSettings("password").ToString
    
    
            Catch ex As Exception
                MsgBox("Error de conexion(1): " & ex.Message & ". Comuníquese con su administrador de sistemas")
            End Try
        End Sub
    
        Public Function ConnString() As String
    
            Dim MySQLconnectionString As String
            MySQLconnectionString = "Server=" & servidor & ";" & _
                        "Port=" & port & ";" & _
                        "Database=" & database & ";" & _
                        "Uid=" & usuario & ";" & _
                        "Pwd=" & password & ";"
            Return MySQLconnectionString
    
        End Function
    
        Public Function open() As MySqlConnection
    
            Dim MySQLconnectionString As String
            MySQLconnectionString = "Server=" & servidor & ";" & _
                                            "Port=" & port & ";" & _
                                            "Database=" & database & ";" & _
                                            "Uid=" & usuario & ";" & _
                                            "Pwd=" & password & ";"
            Dim conn As New MySqlConnection
    
            Try
    
                conn = New MySqlConnection(MySQLconnectionString)
    
                If conn.State = True Then
                    conn.Close()
                End If
                conn.Open()
                Return conn
            Catch ex As Exception
                MsgBox("Error de conexion(2): " & ex.Message & ". Comuníquese con su administrador de sistemas")
                Return Nothing
    
            End Try
    
        End Function

    Tomando los datos desde... App.config

      <appSettings>
       
        <add key="servidor" value="localhost"/> 
        <add key="database" value="fruty"/>
        <add key="usuario" value="root"/>
        <add key="password" value="root"/>
        <add key="port" value=""/>

      </appSettings>


    Sin embargo, he leído que esta práctica no es segura...

    ¿Cuál sería la mejor manera de hacer una conexion segura? 

    Recuerden por que trabajo vb.net con MySql

    Agradezco su ayuda


    Saludos, Solph.

    martes, 20 de noviembre de 2012 16:35

Todas las respuestas

  • Hola,

    Sin embargo, he leído que esta práctica no es segura...

    A mi me parece que es la mejor practica para armar y utilizar una conexión, leyendo los datos desde un archivo de configuración, para que en caso de que cambie el nombre de la base de datos, usuario o clave de mysql, nombre del servidor, no sea necesario re-compilar y/o re-publicar los fuentes de la aplicación.

    Al código solo le cuestiono una cosa y es la siguiente:

    Tienes un método que se llama ConnString, que efectivamente se encarga de armar y retornar el connectionstring, ese método lo deberias llamar desde el otro método llamado: open, para que no repitas este pedazo de código:

      MySQLconnectionString = "Server=" & servidor & ";" & _
                        "Port=" & port & ";" & _
                        "Database=" & database & ";" & _
                        "Uid=" & usuario & ";" & _
                        "Pwd=" & password & ";"


    Un saludo,
    Cristian Pérez
    Blog

    martes, 20 de noviembre de 2012 16:54
  • Gracias Cristian por tus observaciones...

    La razón por la que no me preocupa es si es o no segura... pues la clave por ejemplo no va encryptada.

    que dices...?


    Saludos, Solph.

    martes, 20 de noviembre de 2012 17:46
  • Pero y entonces porque no encriptas la cadena de conexión.

    Securing Connection Strings

    encriptar conection string del app.config

    Ahí se explica como encriptar el connection string para una mayor seguridad.

    Saludos.


    Cristian Torres
    Blog Cristian Torres

    El Salvador - San Salvador


    martes, 20 de noviembre de 2012 18:04
  • Exacto, cómo dice Cristian Torres, puedes encriptar las claves desde el archivo de configuración cómo explica la dirección que te pasó, o puedes hacer el proceso de criptografia manualmente:

    Namespace TuNamespace
    	'Encriptacion Simetrica, algoritmo de Rijndael, Md5
    	Public Class EncriptaDesdencripta
    		Public Clave As Byte() = Encoding.ASCII.GetBytes("5&(/58Jet7G5r4g%5/&$8&$!")
    		Public IV As Byte() = Encoding.ASCII.GetBytes("Devjoker7.37hAES")
    
    		Public Function Encripta(Cadena As String) As String
    
    			Dim inputBytes As Byte() = Encoding.ASCII.GetBytes(Cadena)
    			Dim encripted As Byte()
    			Dim cripto As New RijndaelManaged()
    			Using ms As New MemoryStream(inputBytes.Length)
    				Using objCryptoStream As New CryptoStream(ms, cripto.CreateEncryptor(Clave, IV), CryptoStreamMode.Write)
    					objCryptoStream.Write(inputBytes, 0, inputBytes.Length)
    					objCryptoStream.FlushFinalBlock()
    					objCryptoStream.Close()
    				End Using
    				encripted = ms.ToArray()
    			End Using
    			Return Convert.ToBase64String(encripted)
    		End Function
    
    
    
    		Public Function Desencripta(Cadena As String) As String
    			Dim inputBytes As Byte() = Convert.FromBase64String(Cadena)
    			Dim resultBytes As Byte() = New Byte(inputBytes.Length - 1) {}
    			Dim textoLimpio As String = [String].Empty
    			Dim cripto As New RijndaelManaged()
    			Using ms As New MemoryStream(inputBytes)
    				Using objCryptoStream As New CryptoStream(ms, cripto.CreateDecryptor(Clave, IV), CryptoStreamMode.Read)
    					Using sr As New StreamReader(objCryptoStream, True)
    						textoLimpio = sr.ReadToEnd()
    					End Using
    				End Using
    			End Using
    			Return textoLimpio
    		End Function
    	End Class
    End Namespace
    
    

    Basicamente esos dos métodos se encargan de encriptar y desencriptar una cadena con MD5.

    A mi me gusta más la alternativa de hacerlo manual, ya que tienes un poco más de control sobre el proceso de cifrado.


    Un saludo,
    Cristian Pérez
    Blog

    martes, 20 de noviembre de 2012 18:12
  • Hola,

    A mi entender yo sugiero tres cosas:

    1.La password deberias guardarla encriptada.

    2.Supongamos que tu aplicacion va a correr en 50 terminales, que vas a hacer ? ir a cada una de las terminales y copiar o cambiar cada archivo de configuracion ?, imaginate si el dia de mañana cambian de servidor ?.

    La idea de tener un archivo externo para tomar los parametros de conexion a la base esta bien, el tema aca es de donde tomarlo ?, para mi deberias tomarlo de una carpeta compartida en el servidor cosa de tener un solo archivo para todas las terminales.

    3. Porque guardar cada uno de los parametros ?, porque no guardar un solo dato con toda la cadena de conexion exepto la contraseña. Si el dia de mañana tenes que agregar un parametro mas de conexion hay que modificar el codigo fuente. Si vos guardarias un solo dato como por ejemplo: 

      <appSettings>
       
        <add key="ConnectionString" value="server=localhost;database=fruty;uid=root;port=3360;pwd=;/>
        <add key="password" value="root"/>
      </appSettings>

    Vos tomas los valores de ConnectionString y de password, la password la desencriptas, buscas en la variable donde asignas ConnectionString el string pwd=; y lo reemplazas por pwd=micontraseña;

    Se entendio ?

    Victor Koch

     

    martes, 20 de noviembre de 2012 18:28
  • Hola Solp.

    En la cadena de conexión deberías especificar que se encripte, para que no se transmita en texto plano por la red.

    Eso se hacer añadiendo a la cadena de conexión un parámetro:

    Para versiones del conector Mysql inferiores a 6.2.1. Usa Encrypt=true. Por ejemplo:

    server=localhost;database=fruty;uid=root;port=3360;pwd=password;Encrypt=true;

    Y a partir de la versión 6.2.1 usa 

    SslMode=Preferred (para usar la conexión encriptada si se puede)

    o SslMode=Required (para obligar a que la conexión sea encriptada o no funcione).

    En cuanto a guardar la clave en el archivo App.config, yo la encriptaría.

    Saludos.

    martes, 20 de noviembre de 2012 20:00
  • Compañero muy aparte de encriptar la cadena de conexion. no te recomendaria colocar el usuario y el password directamente en el app config.

    Estos valores debes de mandarlos como parametro desde el Formulario de Login y a partir de ello armar tu cadena de conexion.

    Lo que si puede tener tu App Config puede ser el Nombre de la Base de datos, y el nombre o Ip del Servidor.


    Luis Muñoz Hidalgo
    Mi Blog
    Desarrollador de Software
    Trujillo-Perú

    jueves, 22 de noviembre de 2012 3:56
  • Estos valores debes de mandarlos como parametro desde el Formulario de Login y a partir de ello armar tu cadena de conexion.

    Enviar usuario y contraseña de base de datos cómo parámetro desde el formulario de login ?

    Es la peor practica que podrias implementar, no tiene nada de malo almacenar la cadena de conexión en el archivo de configuración, Microsoft lo hace cuando trabajas con asistentes y diría que el 90% de los sistemas de información "decentes" también lo hace y si quieres reforzar la seguridad te mostré dos metodos que se encargan de encriptar y desencriptar cadenas de caracteres.


    Un saludo,
    Cristian Pérez
    Blog


    jueves, 22 de noviembre de 2012 12:41
  • Hola,

    "Estos valores debes de mandarlos como parametro desde el Formulario de Login y a partir de ello armar tu cadena de conexion."

    Veamosle la parte comercial del colega, eso se llama mantener cautivo al cliente.

    Victor Koch.

    jueves, 22 de noviembre de 2012 15:10
  • Mala Practica quien lo dice???

    Entonces que usar cuando se use segurida de SQL SERVER??

    creo quee stas errado.. en tucocnepto..


    Luis Muñoz Hidalgo
    Mi Blog
    Desarrollador de Software
    Trujillo-Perú

    domingo, 25 de noviembre de 2012 1:21