我正在创建一个使用两个会话的登录系统(对于那些不允许使用cookie的人来说(同意 cookie法 ..我正在使用该网站{{3作为参考)
现在,我有这个系统用于我的cookie身份验证
function GenerateString(){
$length = mt_rand(0,25);
$characters = '0123456789abcdefghijklmnopqrstuvwxyz';
$string = '';
for ($p = 0; $p < $length; $p++) {
$string .= $characters[mt_rand(5, strlen($characters) -1)];
}
return $string;
}
$RandomString = GenerateString();
$CookieAuth = $DB->prepare("INSERT INTO cookieauth (Username,RandomString) VALUES (?,?)");
$CookieAuth->bind_param('ss',$_POST['Username'],$RandomString);
$CookieAuth->execute(); // Insert the Authentication Methods into the database
$CookieAuth->close(); // Allow another query/statement
$GetInsertID = $DB->prepare("SELECT ID FROM CookieAuth WHERE RandomString=?");
$GetInsertID->bind_param('s',$Randomstring);
$GetInsertID->execute();
$GetInsertID->bind_result($RowID);
$GetInsertID->fetch();
$GetInsertID->close();
setcookie("Auth[ID]",$RowID);
setcookie("Auth[UName],$_POST['Username']);
setcookie("Auth[RandomString]",$RandomString);
然后处理cookie:
if(isset($_COOKIE['Auth'])){
$Authenticate = $DB->prepare("SELECT Username,RandomString FROM cookieauth WHERE ID=?");
$Authenticate->bind_param('i',$_COOKIE['Auth']['ID']);
$Authenticate->execute();
$Authenticate->bind_result($RowUsername,$RowString);
$Authenticate->fetch();
$Authenticate->close();
if ($_Cookie['Auth']['UName'] == $RowUsername){
if ($_COOKIE['Auth']['RandomString'] == $RowString){
header("Location: LoggedIn.php");
}else{
die("Possible Cookie Manipulation, Autologin Cannot Continue");
}
}else{
die("Possible Cookie Manupulation, Autologin Cannot Continue!");
}
我的总体目标是使用Cookie提供自动登录功能。因为人们应该知道它们本质上是作为纯文本存储在硬盘驱动器上的。所以如果我包含一个随机生成的字符串,每次进一步处理时会更改(然后更新cookie以匹配数据库)这是一种相当安全的方式完成任务?我的意思是,我明白这不是100%安全,因为有些用户可能会尝试操纵随机字符串,所以我可以使用盐,随机密钥然后使用hash_hmac
来sha512 salt +密钥并保存作为饼干......
我的整体问题是,我提供了一种通过cookie处理自动登录的半安全方法,可以最大限度地减少一些坏人操纵密钥以获得所需数据的可能性吗?
答案 0 :(得分:6)
<强>简介强>
为什么要在会话进行时确认cookie?如果您想要更改ID
,则可以使用session_regenerate_id
轻松实现该目标,如@MarcB指出的那样。
我的假设
我想假设我没有清楚地理解这个问题,这可能是你想要实现的目标
您已经解决了
我可以使用salt,随机密钥然后使用hash_hmac来sha512 salt + key并将其保存为cookie ...
这正是解决方案,但您需要注意
hash_hmac 512
会以十六进制格式生成126
,您需要了解Browser Cookie Limits因此我建议您将其缩减为256
您的解决方案已修改
如果我们要使用您的解决方案,我们需要一些修改
session_start();
// Strong private key stored Securly stored
// Used SESSION For demo
$privateKey = isset($_SESSION['key']) ? $_SESSION['key'] : mcrypt_create_iv(128, MCRYPT_DEV_URANDOM);
$my = new SignedCookie($privateKey);
$my->setCookie("test", "hello world", time() + 3600);
echo $my->getCookie("test");
输出
hello world
但数据存储方式如下:
这只是使用hash_hmac
来签署和验证您的值,并使用随机变量来确保坏人无法构建可能值的表,因为他们真的不必破坏哈希值。可以只研究它也可以使用之前使用的有效例如。
10 Cookies = AAAA
1 Cookie = BBBB
他可以使用有效会话登录并将Cookie从BBBB
更改为AAAA
,因此即使您不存储到数据库,也始终包含随机参数
您还可以删除这样的Cookie:
$my->setCookie("test", null, time() - 3600);
使用简单类
class SignedCookie {
private $prifix = '$x$';
private $privateKey;
function __construct($privateKey) {
$this->privateKey = $privateKey;
}
function setCookie($name, $value, $expire, $path = null, $domain = null, $secure = null, $httponly = null) {
$value = $value === null ? $value : $this->hash($value, mcrypt_create_iv(2, MCRYPT_DEV_URANDOM));
return setcookie($name, $value, $expire, $path, $domain, $secure, $httponly);
}
function getCookie($name, $ignore = false) {
if (! isset($_COOKIE[$name]) || empty($_COOKIE[$name]))
return null; // does not exist
if ($ignore === false) {
if (substr($_COOKIE[$name], 0, 3) !== $this->prifix)
return - 1; // modified
$data = pack("H*", substr($_COOKIE[$name], 3)); // Unpack hex
$value = substr($data, 32, - 2); // Get Value
$rand = substr($data, - 2, 2); // Get Random prifix
if ($this->hash($value, $rand) !== $_COOKIE[$name])
return - 1; // modified
return $value;
}
return $_COOKIE[$name];
}
function hash($value, $suffix) {
// Added random suffix to help the hash keep changing
return $this->prifix . bin2hex(hash_hmac('sha256', $value . $suffix, $this->privateKey, true) . $value . $suffix);
}
}
<强>结论强>
您不是安全专家只是使用,所以只需使用 SSL (SSL also has its issues but far better)或查找现有的安全身份验证服务。 @ircmaxell最近提醒我Schneier's Law:
@Baba:“惊喜”是安全的敌人。私钥唯一应该保密的东西。记住Schneier定律:任何人都可以发明一种他们自己无法破解的加密方案。我的答案基于经过验证的真实加密原则。
我认为你也应该接受这个建议。