首次为网页创建登录系统,我一直试图了解安全性,但不确定我是否正确行事。
到目前为止,我已存储用户名/密码,密码使用sha256和3个char盐进行哈希处理。如果用户名和密码正确,那么我创建一个像这样的新会话ID
session_regenerate_id ();
$_SESSION['valid'] = 1;
$_SESSION['userid'] = $userid;
在我查看的每一页
function isLoggedIn()
{
if(isset($_SESSION['valid']) && $_SESSION['valid'])
return true;
return false;
}
我用它来检查正确的用户
$username = $_POST['username'];
$password = $_POST['password'];
//connect to the database here
connect();
//save username
$username = mysql_real_escape_string($username);
//query the database for the username provided
$query = "SELECT password, salt
FROM users
WHERE username = '$username';";
$result = mysql_query($query);
if(mysql_num_rows($result) < 1) //no such user exists
{
//show incorrect login message
}
//check the password is correct for the username found
$userData = mysql_fetch_array($result, MYSQL_ASSOC);
$hash = hash('sha256', $userData['salt'] . hash('sha256', $password) );
if($hash != $userData['password']) //incorrect password
{
//show incorrect login message
}
else
{
//setup a new session
validateUser();
//redirect to the main page
header('Location: main.php');
die();
如果为false,则会将其发送回登录页面。这足够安全吗?
在主页面中我也有html链接
<li><a href="main.php">Home page</a>
所以我需要在使用这些链接时在主页面上结束php脚本吗?
答案 0 :(得分:4)
添加phpdev所说的内容。即使它看起来足够安全,但我还是会推荐几件事。
当您想要将用户发送到某个页面时,请确保您的脚本退出并完成执行,因为如果仍然有一些行将被执行。以此为例:
if (!isLoggedIn()){
header('Location: login.php');
}
//It's wrong to assume that things are safe here
echo $secret_data;
因此请务必在exit();
来电后添加die();
或header()
。
此外,在散列时,请确保您使用每个用户的唯一salt ,因此您需要在users
表中创建一个额外的列以存储salt
到哈希密码。强烈建议使用经过良好测试的库进行散列,例如PHPass。
如果您使用相同的域在同一Web服务器上运行不同的Web服务,例如:
mysite.com/my_super_awesome_app
和mysite.com/my_not_very_awesome_app
确保您在$_SESSION
$_SESSION['app1_valid']
中为变量名称添加前缀,或使用session_set_cookie_params()
将会话Cookie限制为某个路径
答案 1 :(得分:3)
是的,这看起来很安全。只需确保在执行任何操作之前致电session_start()
,并注意设置$_SESSION['valid']
的位置。确保仅在确认他们输入了正确的用户名和密码后才设置。
至于腌制,我建议每个用户使用一个大约10个字符的独特盐。然后使用带有blowfish算法(bcrypt)的crypt对结果进行哈希处理。 BCrypt的设计使得计算哈希值的成本越来越高,如果有人窃取你的密码哈希值,这很重要。
答案 2 :(得分:2)
不要忘记从登录表单向前要求HTTPS,否则这一切都是无用的。
答案 3 :(得分:0)
基本应用程序看起来不错。你可以做更多的事情。计时器。字典攻击。登录尝试会话。搜索SO。
function is_customer_logged_in() {
if($_COOKIE['GC_CUST_LOGIN']==1 && $_SESSION["loggedIn"]=="1"){
return true;
}else{
return false;
}
}
$_SESSION["time"]=time();
setcookie("GC_CUST_LOGIN", 1, ".stackoverflow.com");
$_SESSION["loggedIn"]="1";
$_SESSION["loggedIn_Md5_Hash"]=md5(hash);
您还可以为会话插入哈希值,检查是否已登录并添加号码,并在数据库检查后使用Cookie和会话强制匹配。
答案 4 :(得分:0)
密码安全性需要考虑很多事情。不幸的是,sha-256仍然没有击败bcrypt或scrypt(它们实现了关键的拉伸,盐和可扩展的工作因素,以帮助硬件改进)。
我会通过openwall(http://www.openwall.com/phpass/)查看PHPass这是一个非常标准的bcrypt库,易于使用。
正如其他人所说,除非你的登录页面是通过HTTPS保护的,否则密码仍然可以被嗅探。
我喜欢你正在重新生成session_id。虽然在这种情况下它可能无关紧要,但它有助于防止会话重放或会话固定攻击。
要使您的系统更安全,还需要考虑其他一些事项: