Get varbinary (50) from SQL Server to byte [] in C #

1

I'm doing a Login , in which the user's password stored in the Database is of type varbinary(50) I must recover this value, to later compare it with the key string entered by the user.

In the Database I have the following:

  

password = 0x61646D696E in string is admin using the Encoding.ASCII .

I have done the following (assume the connection cnn is open):

string comando = string.Empty;
DataSet dataset = new DataSet();

byte[] claveByte = Encoding.ASCII.GetBytes(txt_clave.Text.Trim());
string claveString = "0x" + BitConverter.ToString(claveByte).Replace("-", string.Empty);

comando = @"select nombre_usuario, convert(varchar(50), password, 1) as clave from USUARIO 
            where nombre_usuario = '" + txt_usuario.Text.Trim() + "'" +
            " and password =" + claveString;

using (SqlDataAdapter sentencia = new SqlDataAdapter(comando, cnn))
{
       sentencia.Fill(dataset);
       sentencia.Dispose();
}

byte[] claveObtenida = Encoding.ASCII.GetBytes(dataset.Tables[0].Rows[0]["clave"].ToString());
usuario = dataset.Tables[0].Rows[0]["nombre_usuario"].ToString();
clave = Encoding.ASCII.GetString(claveObtenida);

if (txt_usuario.Text == usuario && txt_clave.Text == clave)
{
    //.........
    //........
}
  

txt_usuario.Text = "admin"; and txt_clave.Text = "admin"; , when converting the key obtained from the database to string I get the following:

Is there a better way to do it without involving the use of so many type conversions and being able to correctly buy the user's password?

Entordo: Visual Studio 2010 (WindowsForms) C #, .NET NetFrameWork 4.

    
asked by J. Rodríguez 06.04.2018 в 15:27
source

2 answers

1

There are many things you can improve in your code.

First, use parameters in your query, otherwise you will be exposed to SQL injection

var command = new SqlCommand();
command.CommandText = @"
select nombre_usuario, convert(varchar(50), password, 1) as clave 
from USUARIO 
where nombre_usuario = @usuario and password = @password";

Second, if your field is a binary, compare binaries with binaries you do not need to convert:

byte[] claveByte = Encoding.ASCII.GetBytes(txt_clave.Text.Trim());
command.Parameters.Add("@password", claveByte);

Third, that the password is in binary does not mean that it is safe, I now know that you are simply storing the encoded ASCII, I can steal your database (I will not do it: p) and I can decode it.

I recommend you research and use something like RNGCryptoServiceProvider .

Your code could be like this:

var command = new SqlCommand();
command.CommandText = @"
select nombre_usuario, convert(varchar(50), password, 1) as clave 
from USUARIO 
where nombre_usuario = @usuario and password = @password";

command.Parameters.Add(new SqlParameter("@usuario", txt_usuario.Text));
command.Parameters.Add(new SqlParameter("@password", Encoding.ASCII.GetBytes(txt_clave.Text.Trim())));

if(command.ExecuteScalar() == null)
{
    return "Bad Password";
}
else
{
    return "Good Password";
}
    
answered by 06.04.2018 / 15:41
source
1

I will try to complement the response of @hardkoded a bit. To manage the password for the login you wish to implement, I do not recommend using a process to encrypt and decrypt the key, my recommendation would be to use a cryptographic hash function. This hash function will always return the same result for the value you enter, if you enter another value it will generate a result completely different from the previous one. I leave you link with the hash functions available in .net. Do not use MD5 or SHA1 since they are not very safe and it is not recommended to continue using them, you can use SHA256, SHA384, SHA512.

link

Pseudocode of how this would work:

First case Insert New user:

  1- Lees usuario y password ingresado por el usuario.
  2- Hash = FuncionHashCriptografica(password) //obtienes el hash del password
  3- Insertas en BD Usuario y Hash obtenido en el paso anterior.

Second case login:

 1- Lees usuario y password ingresado por el usuario.
 2- Hash = FuncionHashCriptografica(password) //obtienes el hash del password
 3- BuscarUsuarioEnBD(usuario, Hash)
 4- Si retorno un usuario procedes con iniciar sesión
 5- Si no retorno un usuario puede significar dos cosas. O el usuario no existe o que el password ingresado no es el correcto.

As you can see in the second case to log in, the comparison of the keys is based on the hash generated from the text entered by the user in the password field, what is in BD is not decrypted.

I hope it helps you.

    
answered by 06.04.2018 в 19:23