Brian
asked on
Forgot your password help
Hello Experts,
I have an application that I need to give users the ability to reset their password. So far I have a process that works half way. Please see what I have below along with code. My question(s) is I need help with encrypting/decrypting the usersid when they recieve an email. I don't want the user to be able to reset anyone elses password by guessing another usersid.
Step 1: User needs to enter his/her username and email address. If correct an email will be sent with a link to the user.
Step 2: User recieves link and will need to click on the link and they will be prompted to enter a new password. This is the step that I'm having trouble with. I would like the usersid to be encrypted in the email. When the user clicks on the link I would like to be able to retrievce his/her userid and store it in a HiddenField and have it decrypted at that point. Then user can enter new password to have it reset.
Also, please note that when I enter the actual usersid into the querystring it does not retrieve the users information.
I have an application that I need to give users the ability to reset their password. So far I have a process that works half way. Please see what I have below along with code. My question(s) is I need help with encrypting/decrypting the usersid when they recieve an email. I don't want the user to be able to reset anyone elses password by guessing another usersid.
Step 1: User needs to enter his/her username and email address. If correct an email will be sent with a link to the user.
Step 2: User recieves link and will need to click on the link and they will be prompted to enter a new password. This is the step that I'm having trouble with. I would like the usersid to be encrypted in the email. When the user clicks on the link I would like to be able to retrievce his/her userid and store it in a HiddenField and have it decrypted at that point. Then user can enter new password to have it reset.
Also, please note that when I enter the actual usersid into the querystring it does not retrieve the users information.
Forgot Password CodeBehind:
using System;
using System.Configuration;
using System.Collections.Generic;
using System.Security.Cryptography;
using System.Data;
using System.Data.SqlClient;
using System.IO;
using System.Net.Mail;
using System.Net.NetworkInformation;
using System.Text;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.IO;
public partial class application_forgotpassword : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
lblForgotPasswordError.Visible = false;
}
protected void SendForgotPasswordEmail()
{
SmtpClient smtpClient = new SmtpClient();
MailMessage message = new MailMessage();
MailAddress fromAddress = new MailAddress("no-reply@domain.org", "Reporting System");
MailAddress toAddress = new MailAddress(HttpUtility.HtmlEncode(txtWorkEmail.Text));
message.From = fromAddress;
message.To.Add(toAddress);
string EMPURL = "<span style=\"font-size: 14px; color: #0c9b19; font-family: Arial\"><font face='arial' color='#666666'>" + "Click <a href='http://application/resetpassword.aspx?emp_id=" + hf_emp_id.Value + "'>here </a>to reset your password.";
message.Subject = "Reset your Password";
message.IsBodyHtml = true;
message.Body = "<html><head><title>" + "</title></head><body>" + "<p>" + "<span style=\"font-size: 16px; color: #0c9b19; font-family: Arial\"><b>Forgot your password?</b><font face='arial' color='#666666'>" + "<br /><br />" + EMPURL + "<span style=\"font-size: 12px; font-style: italic; color: #de1919; font-family: Arial\"><br />" + "<span style=\"font-size: 14px; font-style: italic; color: #de1919; font-family: Arial\"><br /><br />" + "** Passwords are secure. Please make sure that you remember your password or store it in a safe place. **" + "</body></html>";
smtpClient.Host = "mail.domain.org";
smtpClient.Send(message);
}
protected void btn_forgotpassword_Click(object sender, EventArgs e)
{
using (SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["WellnessTracker"].ConnectionString))
{
SqlCommand cmd = new SqlCommand();
cmd.CommandText = "RetrieveForgottenPassword";
cmd.CommandType = CommandType.StoredProcedure;
cmd.Connection = conn;
cmd.Parameters.Add("@emp_username", SqlDbType.VarChar, 50).Value = txtUserName.Text;
cmd.Parameters.Add("@emp_email", SqlDbType.VarChar, 100).Value = txtWorkEmail.Text;
try
{
conn.Open();
SqlDataReader rdr = cmd.ExecuteReader();
if (rdr.Read())
{
hf_emp_id.Value = EncryptDecryptQueryString.EncodeTo64(rdr["emp_id"].ToString());
SendForgotPasswordEmail();
Response.Redirect("forgotpasswordsuccess.aspx");
}
else
{
lblForgotPasswordError.Text = "We are unable to locate your account.";
}
}
catch (Exception ex)
{
lblForgotPasswordError.Text = ex.Message.ToString();
}
}
}
}
EncryptDecryptQueryString Class:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Security.Cryptography;
/// <summary>
/// Summary description for EncryptDecryptQueryString
/// </summary>
public class EncryptDecryptQueryString
{
public static string EncodeTo64(string toEncode)
{
byte[] toEncodeAsBytes = System.Text.Encoding.Unicode.GetBytes(toEncode);
string returnValue = System.Convert.ToBase64String(toEncodeAsBytes);
return returnValue;
}
/// <summary>
/// The method to Decode your Base64 strings.
/// </summary>
/// <param name="encodedData">The String containing the characters to decode.</param>
/// <returns>A String containing the results of decoding the specified sequence of bytes.</returns>
public static string DecodeFrom64(string encodedData)
{
byte[] encodedDataAsBytes = System.Convert.FromBase64String(encodedData);
string returnValue = System.Text.Encoding.Unicode.GetString(encodedDataAsBytes);
return returnValue;
}
}
RetrieveForgottenPassword Stored Procedure:
ALTER PROCEDURE [dbo].[RetrieveForgottenPassword]
(
@emp_username varchar(50),
@emp_email varchar(100)
)
AS
SELECT emp_id, emp_username, emp_email
FROM Employees
WHERE emp_username = @emp_username AND emp_email = @emp_email
Reset Password CodeBehind:
using System;
using System.Configuration;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.IO;
using System.Net.Mail;
using System.Net.NetworkInformation;
using System.Text;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Security.Cryptography;
public partial class application_resetpassword : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
RetrieveEmployeeIDFullName();
lblResetPasswordError.Visible = false;
}
protected void RetrieveEmployeeIDFullName()
{
string empid = EncryptDecryptQueryString.DecodeFrom64(Request.QueryString["emp_id"].ToString());
using (SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["WellnessTracker"].ConnectionString))
{
SqlCommand cmd = new SqlCommand();
cmd.CommandText = "RetrieveEmployeeFirstLastName";
cmd.CommandType = CommandType.StoredProcedure;
cmd.Connection = conn;
cmd.Parameters.Add("@emp_id", SqlDbType.Int).Value = empid;
try
{
conn.Open();
SqlDataReader rdr = cmd.ExecuteReader();
if (rdr.Read())
{
hf_emp_id.Value = rdr["emp_id"].ToString();
lblUsersFullName.Text = rdr["emp_firstname"].ToString();
}
}
catch (Exception ex)
{
ex.Message.ToString();
}
}
}
protected void btn_ResetPassword_Click(object sender, EventArgs e)
{
using (SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["WellnessTracker"].ConnectionString))
{
SqlCommand cmd = new SqlCommand();
cmd.CommandText = "UpdateEmployeesPassword";
cmd.CommandType = CommandType.StoredProcedure;
cmd.Connection = conn;
cmd.Parameters.Add("@emp_id", SqlDbType.Int).Value = hf_emp_id.Value;
cmd.Parameters.Add("@emp_password", SqlDbType.Binary, 96).Value = PasswordHash.HashPassword(txtPassword.Text);
try
{
conn.Open();
cmd.ExecuteNonQuery();
Response.Redirect("resetpassword.aspx");
}
catch (Exception ex)
{
lblResetPasswordError.Text = ex.Message.ToString();
}
}
}
}
Reset Password Stored Procedures:
ALTER PROCEDURE [dbo].[RetrieveEmployeeFirstLastName]
(
@emp_id int
)
AS
SELECT emp_id, emp_firstname, emp_lastname
FROM dbo.Employees
WHERE emp_id = @emp_id
ASKER
So I don't need to use a hiddenfield on either page of those pages or code?
Yes, As you can
1.Retrieve username from textbox itself while encrypting.
2.Retrieve username from querystring itself while decrypting
So, there is no need of hidden field .
1.Retrieve username from textbox itself while encrypting.
2.Retrieve username from querystring itself while decrypting
So, there is no need of hidden field .
ASKER
What did you think about the encryption/decryption that I'm using. Actually I think it only encodes/decodes.
Do you know of a more secure or better approach?
Do you know of a more secure or better approach?
What did you think about the encryption/decryption that I'm using. ?If its more of a secure kinda of site , you can use security question concept for further provide a secure layer inorder to reset password but its just my view .
Several Encryption Techniques which i found useful:
http://www.c-sharpcorner.com/uploadfile/aa04e6/query-string-encryption-decryption-technique-in-Asp-Net-3-5/
http://www.dotnetspider.com/resources/30280-Encryption-Decryption-Password-using-VB-NET.aspx
http://www.c-sharpcorner.com/UploadFile/gsparamasivam/CryptEncryption11282005061028AM/CryptEncryption.aspx
http://www.freevbcode.com/ShowCode.asp?ID=4520
http://filedb.experts-exchange.com/incoming/2012/03_w12/562243/SampleCode.txt
http://alanfeekery.com/2011/07/14/simple-encrypting-decrypting-of-strings-in-asp-net/
Meeran03
ASKER
Thanks, which algorithim do you suggest for a more secure site?
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Hi meeran03,
Ok, what algorithim do you suggest is better for hashing? That is how I store my passwords now. I can upload the code I'm using to show you if you like if you wouldn't mind looking at it.
Ok, what algorithim do you suggest is better for hashing? That is how I store my passwords now. I can upload the code I'm using to show you if you like if you wouldn't mind looking at it.
hi asp_net2,
2. SHA1
Using SALT on either of your hashing algorithm will give more security .
http://stackoverflow.com/questions/1756188/how-to-use-sha1-or-md5-in-cwhich-one-is-better-in-performance-and-security-fo
Meeran03
what algorithim do you suggest is better for hashing?1. SHA256
2. SHA1
Using SALT on either of your hashing algorithm will give more security .
http://stackoverflow.com/questions/1756188/how-to-use-sha1-or-md5-in-cwhich-one-is-better-in-performance-and-security-fo
I can upload the code..Yes, i wouldnt mind if that was another thread lol . As it varies more than to the original question asked .
Meeran03
However, There is no need of hidden field assignment, just encrypt/decrypt assign it on varaible use it accordingly
Open in new window
Open in new window
Meeran03