Depending in what kind of password I use to store in the database my program crashes on "Consulta" method when its trying to do Reader.close() inside the first "if".
For example if I set as password "1234" I have no problems, with "prueba" instead the crash happens and it doesnt even go to "catch".
This is the method to save a new user, which is in a button event.
private void bbtnGuardar_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
{
DB con = new DB(path);
MD5 md5 = MD5.Create();
byte[] hash = md5.ComputeHash(Encoding.Default.GetBytes(tbPassword.Text));
String encryptedPassword = Encoding.Default.GetString(hash);
string query = "INSERT INTO IEM182_LOGIN (USUARIO, PASSWORD) VALUES " +
"('" + tbUsuario.Text + "', '" + encryptedPassword + "');";
try
{
con.Consulta(query);
MessageBox.Show("Nuevo usuario dado de alta correctamente");
limpiar_usuario();
}
catch
{
try
{
con.Cerrar();
query = "SELECT * FROM IEM182_LOGIN WHERE USUARIO = '" + tbUsuario.Text + "'";
con.Consulta(query);
if (con.Reader.Read())
{
MessageBox.Show("El nombre de usuario ya existe");
}
}
catch
{
MessageBox.Show("El usuario contiene caracteres no validos");
}
con.Cerrar();
}
This is the database class with some methods.
class DB
{
private SqlDataReader rdr;
private string path;
private SqlConnection con;
private SqlCommand cmd;
public DB(string cadenaConexion)
{
path = cadenaConexion;
con = new SqlConnection(path);
}
public void Consulta(string query)
{
if (Conexion.State == System.Data.ConnectionState.Open)
{
cmd = new SqlCommand(query, con);
Reader.Close();
Reader = cmd.ExecuteReader();
}
else
{
con.Open();
cmd = new SqlCommand(query, con);
Reader = cmd.ExecuteReader();
}
}
public SqlDataReader Reader
{
get { return rdr; }
set { rdr = value; }
}
public void Cerrar()
{
con.Close();
}
public SqlConnection Conexion
{
get { return con; }
set { con = value; }
}
This is your problem:
byte[] hash = md5.ComputeHash(Encoding.Default.GetBytes(tbPassword.Text));
String encryptedPassword = Encoding.Default.GetString(hash);
There is absolutely no guarantee that the bytes you get back from a hash algorithm forms a legal unicode string, in fact I would say that it is a very slim chance that this will produce usable strings at all. Seems you have found a few odd cases that do. This is just by chance.
You should not pipe those bytes through Encoding.Default.GetString
, instead you should use something like Base 64 encoding:
String encryptedPassword = Convert.ToBase64String(bytes);
This will produce a string that doesn't have oddball characters that won't survive a roundtrip through the database.
To get the hash bytes back you decode using the same class:
byte[] hash = Convert.FromBase64String(encryptedPassword);
Now, is this the only problem with your code?
No, it isn't.
The second problem, that coupled with the above one, will throw a spanner into your SQL execution is this:
string query = "INSERT INTO IEM182_LOGIN (USUARIO, PASSWORD) VALUES " +
"('" + tbUsuario.Text + "', '" + encryptedPassword + "');";
You should never form a SQL through string concatenation, you should instead use parameters.
Since you've made a method, Consulta
that does this querying, actually modifying your code to use parameters is quite a bit of changes but to execute the above SQL, with parameters , you would do something like this:
string query = "INSERT INTO IEM182_LOGIN (USUARIO, PASSWORD) VALUES " +
"(@username, @password);";
var cmd = new SqlCommand();
cmd.CommandText = query;
cmd.Parameters.AddWithValue("@username", tbUsuario.Text);
cmd.Parameters.AddWithValue("@password", encryptedPassword);
cmd.ExecuteNonQuery();
Exactly how you go about changing your Consultas
method to handle this is up to you, but this is the way you must do it!
So to fix the problem I was having I used another encrypting method
// byte array representation of that string
byte[] encodedPassword = new UTF8Encoding().GetBytes(password);
// need MD5 to calculate the hash
byte[] hash = ((HashAlgorithm)CryptoConfig.CreateFromName("MD5")).ComputeHash(encodedPassword);
// string representation (similar to UNIX format)
string encoded = BitConverter.ToString(hash)
// without dashes
.Replace("-", string.Empty)
// make lowercase
.ToLower();
And fixed the first "try/catch" adding another try/catch to call the con.Consulta() method and to catch the invalid characters.
Thanks you very much https://stackoverflow.com/users/267/lasse-v-karlsen
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.