Reputation: 2057
what i am trying to do is when a user registers the password gets encrypted, and the encrypted password gets saved in a database, and when the user logs in it should then decrypt the password to compare if the user entered the correct password, but when i try to decrypt its gives me a "Bad data" exception.
Please help guys. Here is my code:
protected void btnLogin_Click(object sender, EventArgs e)
{
try
{
private Cryptography crypt = new Cryptography();
var registerUser = new test.Model.User();
registerUser.EmailAddress = txtEmail.Text;
registerUser.Password = txtPassword.Text;
//new test().Getbyusername(registerUser);
new test().getbyemail(registerUser, crypt);
}
catch (Exception ex)
{
}
}
public void getbyemail(User user, Cryptography crypt)
{
try
{
var repo = new UserRepository();
var test = repo.GetEncryptedPasswrd(user);
var o = repo.getPrivateKey(user.EmailAddress);
crypt.privateKey = o;
var j = repo.getpublicKey(user.EmailAddress);
crypt.publicKey = j;
decryptPassword(test, o, crypt);
}
catch (Exception ex)
{
}
}
public String decryptPassword(byte [] encryptedpassword, string privateKey, Cryptography cry)
{
decrypted = cry.decrypt(encryptedpassword, privateKey);
//return Encoding.ASCII.GetString(decrypted);
return Encoding.ASCII.GetString(decrypted);
}
protected void btnRegister_Click(object sender, EventArgs e)
{
Cryptography crypt = new Cryptography();
var registerUser = new test.Model.User();
registerUser.Name = txtName.Text;
registerUser.Surname = txtSurname.Text;
registerUser.EmailAddress = txtEmailAddress.Text;
registerUser.Password = txtPassword.Text;
registerUser.DateRegisterd = DateTime.Now;
new test().RegisterUser(registerUser, crypt.privateKey, crypt.publicKey,crypt, encrypted);
}
public void RegisterUser(User user, string privateKey, string publicKey, Cryptography crypt, byte[] encrypted)
{
try
{
var repo = new UserRepository();
byte[] plainText = Encoding.ASCII.GetBytes(user.Password);
encrypted = crypt.encrypt(plainText, crypt.publicKey);
user.Password = Encoding.ASCII.GetString(encrypted);
user.PrivateKey = crypt.privateKey;
user.PublickKey = crypt.publicKey;
repo.Add(user);
}
catch (Exception ex)
{
}
}
Thanks in advance.
Upvotes: 0
Views: 1650
Reputation: 9800
As said above comment you should really hash it .
Still if you want to encrypt as you example don't decrypt password . Instead you should encrypt password from user and simply compare to database .
You can Consider this simple option to hash the password . http://davidhayden.com/blog/dave/archive/2004/02/16/157.aspx .
Upvotes: 3
Reputation: 1533
there can be a security hole when you're able to decrypt the password. What you should do is encrypt the submitted password as well and compare the encrypted strings.
EDIT: thanks Matthew... that's what i meant...doh
the better question is why aren't you making full use of .net built in login control? You'll need to configure your web.config.
for best security. add the following in your membership provider settings in web.config
enablePasswordRetrieval="False" enablePasswordReset="True" passwordFormat="Hashed"
also add machinekey in
<system.web>
http://www.qualitydata.com/products/aspnet-membership/help/configuration/no-machinekey.aspx
Upvotes: 0
Reputation: 141638
You should not be encrypting passwords. Encryption is a reversable process, so if someone were to steal the encryption key and the passwords, they could get the user's password.
Instead, you should hash the password, and compare the hashes. A hash is destructive - it is impossible to get the original data from a hash. When a user signs up, you store the hash. When they want to sign back in, you hash what they entered and compare the hashes in the database. A hash using an algorithm like SHA-256 can be done like this:
public string GetPasswordHash(string clearPassword)
{
using (var hash = new System.Security.Cryptography.SHA256Managed())
{
var hashBytes = System.Text.Encoding.UTF8.GetBytes(clearPassword);
return Convert.ToBase64String(hash.ComputeHash(hashBytes));
}
}
This gets us a step further, but you should also use a salt as well to prevent attacks like Rainbow Tables. In addition, hashing it multiple times (say 10,000) helps prevent against against brute force attacks. 10,000 hashes is fast for the user logging in, but extremely slow trying to brute force.
Upvotes: 2
Reputation:
I would start with writing a unit test that takes a password, encrypts it an immediately decrypts it.
Once you know that works, make a copy of the encrypted password, and test if you can make a successful roundtrip to the database. If that is binary, encoding it to hex or base64 might help.
Upvotes: 0