用户登录之cookie信息安全
一、cookie信息加密法
cookie信息加密法即用一种加密方法,加密用户信息,然后在存入cookie,这样伪造者即使得到cookie也只能在cookie有效期内对这个cookie利用,无法另外伪造cookie信息。
这里附上一个加密函数:
<!--?php
function
authcode(
$string
,
$operation
=
'DECODE'
,
$key
=
''
,
$expiry
= 0) {
// 动态密匙长度,相同的明文会生成不同密文就是依靠动态密匙
$ckey_length
= 4;
// 密匙
$key
= md5(
$key
?
$key
:
$GLOBALS
[
'discuz_auth_key'
]);
// 密匙a会参与加解密
$keya
= md5(
substr
(
$key
, 0, 16));
// 密匙b会用来做数据完整性验证
$keyb
= md5(
substr
(
$key
, 16, 16));
// 密匙c用于变化生成的密文
$keyc
=
$ckey_length
? (
$operation
==
'DECODE'
?
substr
(
$string
, 0,
$ckey_length
):
substr
(md5(microtime()), -
$ckey_length
)) :
''
;
// 参与运算的密匙
$cryptkey
=
$keya
.md5(
$keya
.
$keyc
);
$key_length
=
strlen
(
$cryptkey
);
// 明文,前10位用来保存时间戳,解密时验证数据有效性,10到26位用来保存$keyb(密匙b),
//解密时会通过这个密匙验证数据完整性
// 如果是解码的话,会从第$ckey_length位开始,因为密文前$ckey_length位保存 动态密匙,以保证解密正确
$string
=
$operation
==
'DECODE'
?
base64_decode
(
substr
(
$string
,
$ckey_length
)) :
sprintf(
'%010d'
,
$expiry
?
$expiry
+ time() : 0).
substr
(md5(
$string
.
$keyb
), 0, 16).
$string
;
$string_length
=
strlen
(
$string
);
$result
=
''
;
$box
= range(0, 255);
$rndkey
=
array
();
// 产生密匙簿
for
(
$i
= 0;
$i
<= 255;
$i
++) {
$rndkey
[
$i
] = ord(
$cryptkey
[
$i
%
$key_length
]);
}
// 用固定的算法,打乱密匙簿,增加随机性,好像很复杂,实际上对并不会增加密文的强度
for
(
$j
=
$i
= 0;
$i
< 256;
$i
++) {
$j
= (
$j
+
$box
[
$i
] +
$rndkey
[
$i
]) % 256;
$tmp
=
$box
[
$i
];
$box
[
$i
] =
$box
[
$j
];
$box
[
$j
] =
$tmp
;
}
// 核心加解密部分
for
(
$a
=
$j
=
$i
= 0;
$i
<
$string_length
;
$i
++) {
$a
= (
$a
+ 1) % 256;
$j
= (
$j
+
$box
[
$a
]) % 256;
$tmp
=
$box
[
$a
];
$box
[
$a
] =
$box
[
$j
];
$box
[
$j
] =
$tmp
;
// 从密匙簿得出密匙进行异或,再转成字符
$result
.=
chr
(ord(
$string
[
$i
]) ^ (
$box
[(
$box
[
$a
] +
$box
[
$j
]) % 256]));
}
if
(
$operation
==
'DECODE'
) {
// 验证数据有效性,请看未加密明文的格式
if
((
substr
(
$result
, 0, 10) == 0 ||
substr
(
$result
, 0, 10) - time() --> 0) &&
substr
(
$result
, 10, 16) ==
substr
(md5(
substr
(
$result
, 26).
$keyb
), 0, 16)) {
return
substr
(
$result
, 26);
}
else
{
return
''
;
}
}
else
{
// 把动态密匙保存在密文里,这也是为什么同样的明文,生产不同密文后能解密的原因
// 因为加密后的密文可能是一些特殊字符,复制过程可能会丢失,所以用base64编码
return
$keyc
.
str_replace
(
'='
,
''
,
base64_encode
(
$result
));
}
}
$str
=
'abcdef'
;
$key
=
'www.phpskill.com'
;
echo
$jm
= authcode(
$str
,
'ENCODE'
,
$key
,0);
//加密
echo
"
";
echo
authcode(
$jm
,
'DECODE'
,
$key
,0);
//解密
?>
这样当设置用户信息的cookie时,就无法对其进行伪造:
<!--?php
$user
=
array
(
"uid"
=-->
$uid
,
"username"
=>
$username
);
$user
=
base64_encode
(serialize(
$user
));
$user
= authcode(
$user
,
'ENCODE'
,
'www.phpskill.com'
,0);
//加密
setcookie(
"user"
,
$user
,time()+3600*24);
?>
二、用加密令牌对cookie进行保护
$hash
= md5(
$uid
.time());
//加密令牌值
$hash_expire
=time()+3600*24;
//加密令牌值为一天有效期
$user
=
array
(
"uid"
=>
$uid
,
"username"
=>
$username
,
"hash"
=>
$hash
);
$user
=
base64_encode
(serialize(
$user
));
setcookie(
"user"
,
$user
,
$hash_expr
);
然后把
$hash
和
$hash_expire
存入member表中hash和hash_expire对应字段中,也可以存入nosql,session
用户伪造cookie时,hash无法伪造,伪造的hash和数据库中的不一致
推荐文章
2024-01-16
2024-01-11
2024-01-04
2023-12-04
2023-11-20
2023-11-14
2023-11-06
2023-10-30
2023-10-13
2023-10-10
稳定
产品高可用性高并发贴心
项目群及时沟通专业
产品经理1v1支持快速
MVP模式小步快跑承诺
我们选择声誉坚持
10年专注高端品质开发