none
Como guardar una password en SQL server

    Pregunta

  • Hola,

    Necesito guardar una paswword proveniente de un textbox.

    Esta passwrod debe ser guardada con algun metodo de ecriptacion quizas MD5 seria bueno.

    Mi pregunta es, ¿Como se hace?

        Sub guardar()
            CN.Open()
            CMD.CommandType = CommandType.Text
            If txtcontraseña.Text <> txtcontraseña2.Text Then
                MessageBox.Show("La contraseña ingresada no son iguales", "Error!", MessageBoxButtons.OK, MessageBoxIcon.Error)
            Else
                CMD.CommandText = "INSERT INTO tblusuarios VALUES('" & txtid.Text & "','" & txtnombre.Text & "','" & txtcontraseña.Text & "','" & combotipo.Text & "')"
                CMD.ExecuteNonQuery()
                MessageBox.Show("El usuario fue creado...")
            End If
            CN.Close()
        End Sub
    Ese es el codigo que hice para guardar los datos, como se ve no tiene ninguna ecriptación.

    atento a sus comentarios.

    Saludos.
    jueves, 18 de junio de 2009 3:52

Respuestas

  • :-)
    Hola,

    Ante todo un consejo: No concatenes tu SQL a partir de los valores de los campos de texto, usa la colección Paramaters del Command. TE lo digo porque si el usuario introduce un carácter (') verás un bonito error, por no mencionar si le da por usar SQL Injection...

    Por otro lado, para guardar un password, lo mejor es usar MD5 para obtener el HASH y guardarlo en la BD. De este modo, cuando el usuario introduce su password para entrar, haces el mismo proceso: Sacas el HASH del password introducido y lo comparas con el de la BD.

    Este código genera el valor HASH de un string mediante MD5:

    Imports System.Security.Cryptography
    Imports System.Text
        Private Sub endButton_Click(sender As Object, e As EventArgs) Handles endButton.Click
            MessageBox.Show(encodePassword("pepeillo"))
        End Sub
        Public Function encodePassword(ByVal originalPassword As String) As String
            Dim md5 As MD5 = New MD5CryptoServiceProvider()
            Dim originalBytes() As Byte = ASCIIEncoding.Default.GetBytes(originalPassword)
            Dim encodedBytes() As Byte = md5.ComputeHash(originalBytes)
            Return Convert.ToBase64String(encodedBytes)
        End Function
    Saludos,

    No olvides marcar la respuesta como correcta si te ha sido de utilidad :-)

    [MS-MVP-MCTS]

    Mi Perfil MVP en: https://mvp.support.microsoft.com/profile/Lluis
    NUG: http://andorradotnet.com
    Web: http://www.ordeeno.com
    Blog: http://msmvps.com/blogs/lfranco
    Geeks: http://geeks.ms/blogs/lfranco


    jueves, 18 de junio de 2009 14:15
    Moderador
  • "memocaceres" preguntó:

    > quiero guardar el resultado que es una cadena a un campo de una tabla de la base
    > de datos tipo varbinary(8000) pero me envia el error: ERROR AL CONVERTIR EL VALOR
    > DEL PARAMETRO DE STRING A BYTE.
    >
    > .CommandText = "INSERT INTO Usuario (CodUsuario, Usuario, Clave, ConfClave) VALUES (@co,@us,@ms,@ms)"
    > .Parameters.Add("@Co", SqlDbType.Int).Value = co
    > .Parameters.Add("@Us", SqlDbType.VarChar, 50).Value = us
    > .Parameters.Add("@ms", SqlDbType.VarBinary, 8000).Value = con
    > .Parameters.Add("@cc", SqlDbType.VarBinary, 8000).Value = cc

    Hola:

    Si has definido en la tabla Usuario el campo Clave con el tipo de dato VarBinary(8000), es normal que obtengas el error que mencionas, porque en lugar de pasarle el valor de una variable alfanumérica (String) le tienes que pasar el valor de una matriz de bytes cuya longitud no supere los 8.000 elementos, que ya son bastantes elementos para el algoritmo MD5, ya que el tamaño de su valor hash siempre será de 128 bits, por lo que su método ComputeHash devolverá una matriz de 16 bytes, no de 8.000 bytes.

    Como son datos de longitud fija (no variable), y sabiendo que su longitud será siempre de 16 bytes, entiendo que lo correcto sería que definieras el campo con el tipo binary(16).

    Pero si el día de mañana tienes pensado cambiar de algoritmo hash para obtener un valor hash con un tamaño superior a los 16 bytes del algoritmo MD5 (que entiendo que está bastante anticuado), podrías definir el tipo de dato del campo como binary(32) o binary(64), por si decides utilizar el algoritmo SHA256SHA512 respectivamente. Los números 256 y 512 indican el tamaño en bits del hash devuelto por los citados algoritmos.

    Si para obtener el hash MD5 vas a utilizar la función EncodePassword que en su día publicó el compañero Lluís Franco en ésta misma conversación, tienes que modificarla para que devuelva la matriz de bytes que le tienes que pasar a los parámetros definidos como VarBinary(8000):

        Public Shared Function EncrypClave(originalPassword As String) As Byte()
    
            Using md5 As New MD5CryptoServiceProvider()
                Dim originalBytes() As Byte = ASCIIEncoding.Default.GetBytes(originalPassword)
                Return md5.ComputeHash(originalBytes)
            End Using
    
        End Function

    Y cuando desees añadir un nuevo registro a tu tabla Usuario, ejecutarías el siguiente código:

            Dim co As String = LblCod.Text
            Dim us As String = TxtNomUsu.Text
            Dim con As Byte() = EncrypClave(TxtCla.Text)
            Dim cc As Byte() = EncrypClave(TxtConfCla.Text)
    
            Try
                Using conexion As New SqlConnection(Escribe aquí tu cadena de conexión)
                    Dim com As SqlCommand = conexion.CreateCommand()
                    com.CommandText = "INSERT INTO Usuario (CodUsuario, Usuario, Clave, ConfClave) VALUES (@co,@us,@ms,@ms)"
                    com.Parameters.AddWithValue("@co", co)
                    com.Parameters.AddWithValue("@us", us)
                    com.Parameters.AddWithValue("@ms", con)
                    com.Parameters.AddWithValue("@cc", cc)
                    conexion.Open()
                    com.ExecuteNonQuery()
                End Using
    
            Catch ex As Exception
                ' Se ha producido un error
                MessageBox.Show(ex.Message)
    
            End Try

    Que no se te olvide especificar tu cadena de conexión con la base de datos de SQL Server en el constructor del objeto SqlConnection.

    Observa que si encerramos el objeto SqlConnection entre un bloque Using ... End Using, no tienes que preocuparte de cerrar y destruir la conexión.

    > como es password el campo prefiero guardarlo en la bd como tipo binario ya que
    > si lo guardo como cadena facilmento podrian sobreescribirla por un texto
    > cualquiera e ingresar a la bd.

    Si alguien tiene acceso a tu base de datos de SQL Server y desea fastidiarte los algoritmos hash almacenados en la tabla Usuario, te los va a fastidiar de igual manera, se encuentren almacenados como valores alfanuméricos o como valores binarios. ;-)

    Un saludo


    Enrique Martínez Montejo
    [MS MVP - Visual Studio y Tecnologías de Desarrollo]

    Nota informativa: La información contenida en este mensaje, así como el código fuente incluido en el mismo, se proporciona «COMO ESTÁ», sin garantías de ninguna clase, y no otorga derecho alguno. Usted asume cualquier riesgo al poner en práctica, utilizar o ejecutar lo recomendado o sugerido en el presente mensaje.

    Si esta respuesta le ha resultado útil, recuerde marcarla como satisfactoria.

    Si usas Visual Basic .NET y deseas ser productivo y feliz, se inteligente y activa la instrucción
    Option Strict.




    miércoles, 10 de agosto de 2016 15:36
    Moderador

Todas las respuestas

  • hola
    si lo que quieres es abrir la Base con codigo puedes probar asi
    "Data Source=|DataDirectory|\MyDatabase#2.sdf;Password=aaaaa#aaaaa1"
    
    
    
    
    
    

    y si lo que quieres es que cada usuario tenga una cantraseña y luego que la inserten para lo que sea tendras que guardarla en una columna y que cada fila de usuario tenga esa contraseña

    Primero comprueba la contraseña del usuario :
    "SELECT        ColumnaDato1 , ColumnaPassword1 , ColumnaUsuario1
    FROM            Tabla1
    WHERE        (ColumnaUsuario1 = @ColumnaUsuario1)"

    para que funcione le pondrias un If que manege la vuelta del Pasword , por si no coincide salte el mensage de " La contraseña no es correcta "
    y despues reescrive el o los datos

    "UPDATE   Tabla1
     SET     ColumnaDato1 = @InColumnaDato1   
    WHERE    (ColumnaUsuario1 = @ColumnaUsuario1) "

     

    espero que sirva de halgo , yo esque siempre utilizo Query para trabajar desconectodo

    • Propuesto como respuesta IvanOnilDj jueves, 18 de junio de 2009 8:37
    jueves, 18 de junio de 2009 8:35
  • :-)
    Hola,

    Ante todo un consejo: No concatenes tu SQL a partir de los valores de los campos de texto, usa la colección Paramaters del Command. TE lo digo porque si el usuario introduce un carácter (') verás un bonito error, por no mencionar si le da por usar SQL Injection...

    Por otro lado, para guardar un password, lo mejor es usar MD5 para obtener el HASH y guardarlo en la BD. De este modo, cuando el usuario introduce su password para entrar, haces el mismo proceso: Sacas el HASH del password introducido y lo comparas con el de la BD.

    Este código genera el valor HASH de un string mediante MD5:

    Imports System.Security.Cryptography
    Imports System.Text
        Private Sub endButton_Click(sender As Object, e As EventArgs) Handles endButton.Click
            MessageBox.Show(encodePassword("pepeillo"))
        End Sub
        Public Function encodePassword(ByVal originalPassword As String) As String
            Dim md5 As MD5 = New MD5CryptoServiceProvider()
            Dim originalBytes() As Byte = ASCIIEncoding.Default.GetBytes(originalPassword)
            Dim encodedBytes() As Byte = md5.ComputeHash(originalBytes)
            Return Convert.ToBase64String(encodedBytes)
        End Function
    Saludos,

    No olvides marcar la respuesta como correcta si te ha sido de utilidad :-)

    [MS-MVP-MCTS]

    Mi Perfil MVP en: https://mvp.support.microsoft.com/profile/Lluis
    NUG: http://andorradotnet.com
    Web: http://www.ordeeno.com
    Blog: http://msmvps.com/blogs/lfranco
    Geeks: http://geeks.ms/blogs/lfranco


    jueves, 18 de junio de 2009 14:15
    Moderador
  • las forma facil de guardarla es:

    FormsAuthentication.HashPasswordForStoringInConfigFile(TextBox1.Text,

    "MD5")

    ese valor lo almacena como un dato cualquiera


    jaysson
    jueves, 18 de junio de 2009 22:07
  • Hola,

    Todo este código para encryptar es correcto, pero ahora quiero guardar el resultado que es una cadena a un campo de una tabla de la base de datos tipo varbinary(8000) pero me envia el error: ERROR AL CONVERTIR EL VALOR DEL PARAMETRO DE STRING A BYTE.

    como es password el campo prefiero guardarlo en la bd como tipo binario ya que si lo guardo como cadena facilmento podrian sobreescribirla por un texto cualquiera e ingresar a la bd. mi código es el siguiente

       Dim us$, co$, con$, cc$
                co = LblCod.Text
                us = TxtNomUsu.Text
                con = EncrypClave(TxtCla.Text)
                cc = EncrypClave(TxtConfCla.Text)

      Conexion.Open()
                    Com = New SqlClient.SqlCommand
                    With Com
                        .Connection = Conexion
                        .CommandText = "INSERT INTO Usuario (CodUsuario, Usuario, Clave, ConfClave) VALUES (@co,@us,@ms,@ms)"
                        .Parameters.Add("@Co", SqlDbType.Int).Value = co
                        .Parameters.Add("@Us", SqlDbType.VarChar, 50).Value = us
                        .Parameters.Add("@ms", SqlDbType.VarBinary, 8000).Value = con
                        .Parameters.Add("@cc", SqlDbType.VarBinary, 8000).Value = cc
                        .ExecuteNonQuery()
                     End With

    conexion.close

    el código de la funcion de EncrypClave es el que tu propones y esta correcto, el problema es al guardar la cadena resultante que genera el error arriba descrito.

    Gracias de antemano

    • Editado memocaceres martes, 09 de agosto de 2016 20:44
    martes, 09 de agosto de 2016 20:38
  • "memocaceres" preguntó:

    > quiero guardar el resultado que es una cadena a un campo de una tabla de la base
    > de datos tipo varbinary(8000) pero me envia el error: ERROR AL CONVERTIR EL VALOR
    > DEL PARAMETRO DE STRING A BYTE.
    >
    > .CommandText = "INSERT INTO Usuario (CodUsuario, Usuario, Clave, ConfClave) VALUES (@co,@us,@ms,@ms)"
    > .Parameters.Add("@Co", SqlDbType.Int).Value = co
    > .Parameters.Add("@Us", SqlDbType.VarChar, 50).Value = us
    > .Parameters.Add("@ms", SqlDbType.VarBinary, 8000).Value = con
    > .Parameters.Add("@cc", SqlDbType.VarBinary, 8000).Value = cc

    Hola:

    Si has definido en la tabla Usuario el campo Clave con el tipo de dato VarBinary(8000), es normal que obtengas el error que mencionas, porque en lugar de pasarle el valor de una variable alfanumérica (String) le tienes que pasar el valor de una matriz de bytes cuya longitud no supere los 8.000 elementos, que ya son bastantes elementos para el algoritmo MD5, ya que el tamaño de su valor hash siempre será de 128 bits, por lo que su método ComputeHash devolverá una matriz de 16 bytes, no de 8.000 bytes.

    Como son datos de longitud fija (no variable), y sabiendo que su longitud será siempre de 16 bytes, entiendo que lo correcto sería que definieras el campo con el tipo binary(16).

    Pero si el día de mañana tienes pensado cambiar de algoritmo hash para obtener un valor hash con un tamaño superior a los 16 bytes del algoritmo MD5 (que entiendo que está bastante anticuado), podrías definir el tipo de dato del campo como binary(32) o binary(64), por si decides utilizar el algoritmo SHA256SHA512 respectivamente. Los números 256 y 512 indican el tamaño en bits del hash devuelto por los citados algoritmos.

    Si para obtener el hash MD5 vas a utilizar la función EncodePassword que en su día publicó el compañero Lluís Franco en ésta misma conversación, tienes que modificarla para que devuelva la matriz de bytes que le tienes que pasar a los parámetros definidos como VarBinary(8000):

        Public Shared Function EncrypClave(originalPassword As String) As Byte()
    
            Using md5 As New MD5CryptoServiceProvider()
                Dim originalBytes() As Byte = ASCIIEncoding.Default.GetBytes(originalPassword)
                Return md5.ComputeHash(originalBytes)
            End Using
    
        End Function

    Y cuando desees añadir un nuevo registro a tu tabla Usuario, ejecutarías el siguiente código:

            Dim co As String = LblCod.Text
            Dim us As String = TxtNomUsu.Text
            Dim con As Byte() = EncrypClave(TxtCla.Text)
            Dim cc As Byte() = EncrypClave(TxtConfCla.Text)
    
            Try
                Using conexion As New SqlConnection(Escribe aquí tu cadena de conexión)
                    Dim com As SqlCommand = conexion.CreateCommand()
                    com.CommandText = "INSERT INTO Usuario (CodUsuario, Usuario, Clave, ConfClave) VALUES (@co,@us,@ms,@ms)"
                    com.Parameters.AddWithValue("@co", co)
                    com.Parameters.AddWithValue("@us", us)
                    com.Parameters.AddWithValue("@ms", con)
                    com.Parameters.AddWithValue("@cc", cc)
                    conexion.Open()
                    com.ExecuteNonQuery()
                End Using
    
            Catch ex As Exception
                ' Se ha producido un error
                MessageBox.Show(ex.Message)
    
            End Try

    Que no se te olvide especificar tu cadena de conexión con la base de datos de SQL Server en el constructor del objeto SqlConnection.

    Observa que si encerramos el objeto SqlConnection entre un bloque Using ... End Using, no tienes que preocuparte de cerrar y destruir la conexión.

    > como es password el campo prefiero guardarlo en la bd como tipo binario ya que
    > si lo guardo como cadena facilmento podrian sobreescribirla por un texto
    > cualquiera e ingresar a la bd.

    Si alguien tiene acceso a tu base de datos de SQL Server y desea fastidiarte los algoritmos hash almacenados en la tabla Usuario, te los va a fastidiar de igual manera, se encuentren almacenados como valores alfanuméricos o como valores binarios. ;-)

    Un saludo


    Enrique Martínez Montejo
    [MS MVP - Visual Studio y Tecnologías de Desarrollo]

    Nota informativa: La información contenida en este mensaje, así como el código fuente incluido en el mismo, se proporciona «COMO ESTÁ», sin garantías de ninguna clase, y no otorga derecho alguno. Usted asume cualquier riesgo al poner en práctica, utilizar o ejecutar lo recomendado o sugerido en el presente mensaje.

    Si esta respuesta le ha resultado útil, recuerde marcarla como satisfactoria.

    Si usas Visual Basic .NET y deseas ser productivo y feliz, se inteligente y activa la instrucción
    Option Strict.




    miércoles, 10 de agosto de 2016 15:36
    Moderador
  • Exelente aporte

    realice las correcciones y me funcionó de maravilla, definitivamente debía declarar la variable tipo arreglo de Byte y ha funcionado.

    Muchas gracias... te doy 10 puntos.

    miércoles, 10 de agosto de 2016 23:33