如何让注册用户的加密密码在登录时被接受为普通密码? [关闭]
Posted
技术标签:
【中文标题】如何让注册用户的加密密码在登录时被接受为普通密码? [关闭]【英文标题】:How can I make a registered user's encrypted password be accepted as the normal password when logging in? [closed] 【发布时间】:2012-12-14 16:51:56 【问题描述】:我最近创建了一个注册页面,用户可以在其中注册并创建自己的帐户。但是如果我退出然后重新进入帐户并尝试登录,则只接受加密版本的密码。如何让我的 loguserin 函数与我的数据库对话,并让它明白它实际上是用户最初输入的普通密码?
控制器:
function loguserin()
$this->load->helper(array('form', 'url'));
$this->load->library('form_validation');
$this->form_validation->set_rules('username', 'Username', 'required|min_length[4]|max_length[12]|callback_validateUser|trim');
$this->form_validation->set_rules('password', 'Password', 'required|md5|trim');
if ($this->form_validation->run())
$username = $this->input->post('username');
$password = $this->input->post('password');
$this->session->set_userdata('status', 'OK');
$this->session->set_userdata('username', $username);
redirect('home');
else
$this->session->set_userdata('status', 'NOT_OK');
$this->load->view('shared/header');
$this->load->view('account/logintitle');
$this->load->view('account/loginview');
$this->load->view('shared/footer');
function validateUser($username, $password)
$this->db->select('*')->from('membership');
$this->db->where('username', $username);
$this->db->where('password',MD5($password));
$query = $this->db->get();
if ($query ->num_rows ==1)
$this->form_validation->set_message('validateUser', 'Invalid username/password');
return false;
else
return true;
【问题讨论】:
"加密密码" — 请不要有真正加密的密码。密码是散列,而不是加密。 MD5 已过时,请移至 Blowfish。 us2.php.net/manual/en/function.crypt.php 已加密;但不安全。在彩虹表中查找可以快速找到最常见的密码。例如;你的密码是'gaga'。 我刚刚搜索了 MD5 哈希 - 这听起来安全吗? @FergusMorrow 它是未加密的。它(很差)散列。 是的,我使用加密是因为没有更好的词。你是 100% 正确的@PeeHaa。 【参考方案1】:在我看来,您的问题是出于安全考虑,在注册时对密码进行了哈希处理。
在这种情况下,您必须知道使用了什么散列函数。例如crypt。比你应该在进行查询之前简单地加密用户输入。
$hashedPassword = crypt($password);
$this->db->select('*')->from('membership');
$this->db->where('username', $username);
$this->db->where('password', $hashedPassword);
$query = $this->db->get();
Here 是 PHP 对密码哈希的建议。
【讨论】:
【参考方案2】:可能看起来 CodeIgniter 没有使用 MD5 加密密码;在set_rules()
:
$this->form_validation->set_rules('password', 'Password', 'required|md5|trim');
验证这一点的一种方法是将其内容转储到显示器上。比如……
var_dump( $this->input->post('password') );
如果密码看起来仍然是纯文本;然后 set_rules 没有在变量上运行 md5() ,这需要一些故障排除。
为了将来参考,一般来说,认证系统会将用户详细信息保存在数据库中;包括密码和用户名的散列版本。 PHP 应用程序将启动一个 SQL 命令,如SELECT password FROM users WHERE USERNAME=username
; 如果没有返回行,则用户名不正确。
然后通过散列方法运行用户输入 - 这与从数据库中检索的值进行比较。 如果这些不匹配,则密码错误。
但是,您似乎在数据库查询中同时发送了密码和用户名;虽然这会起作用 - 您将无法确定是错误的用户名还是错误的密码导致了身份验证问题。
出于这样的原因,通常最好...
尝试使用身份验证框架
有被击落的风险;不要尝试为生产项目编写自己的身份验证代码。只需稍稍疏忽一下,您就可能危及整个应用程序、用户数据等。
有一些非常好的经过验证的身份验证框架 - 我最喜欢的是ion auth,因为它很简单。但是,您可能会找到更喜欢的其他人。
不要只是加密密码;散列它们。
这听起来像是细微的差别;但它实际上非常重要。在您的数据库被破坏的情况下(虽然它很粗鲁!) - 对您的密码进行哈希处理可以提供更好的安全性。尤其是当涉及到彩虹表之类的攻击时。
同样,不要使用md5()
- PHP 有crypt()
函数,它将尝试使用更安全的算法 - 如果系统上可用。此外,它接受第二个参数(这是可选的,但应该使用) - salt。
值得记住的是set_rules()
可以使用crypt()
;至少以最简单的形式(有一个论点)。来自文档:
任何接受一个参数的原生 PHP 函数都可以作为规则使用,如 htmlspecialchars、trim、MD5 等。
【讨论】:
【参考方案3】:根据您用于存储密码的散列,您的模型配置将是这样的:
$this->db->select('*')->from('membership');
$this->db->where('username', $username);
$this->db->where('password', MD5($password));
此外,您的模型中存在用于检查用户是否有效的错误。如果DB返回的行数为1,则用户有效,否则无效。
if ($query->num_rows == 1)
return true;
else
$this->form_validation->set_message('validateUser', 'Invalid username/password');
return false;
【讨论】:
感谢 Abhi 修复了它 感谢 Abhi 的成功,但是如果我的用户还没有注册,我怎样才能让他们无法登录?我的 validateUser 函数应该阻止非注册用户登录,但它没有。请检查我上面的修改代码 我为您刚才提到的问题添加了一些代码。它是您代码中的逻辑错误。此外,一旦这开始按预期工作,您应该研究其他人建议的其他散列方式。 感谢 Abhi 抛出了错误,但信不信由你我的注册用户现在都无法登录,您认为这是什么?会不会是我的 loguserin 函数中的 if else 语句? 尝试在$valid = $this->validateUser($username, $password);
行之后添加var_dump($valid);
。这将判断问题出在模型还是控制器中。以上是关于如何让注册用户的加密密码在登录时被接受为普通密码? [关闭]的主要内容,如果未能解决你的问题,请参考以下文章
MD5加密在用户注册时和用户登陆时怎么用?还有效验接收的文件时的问题