我想生成一个安全的一键访问类型的网址,类似于下面的示例。我将使用PHP但这是无关紧要的,因为我只是想了解基本概念。一些答案建议使用GUID,但我认为这不会给我一个绝对独特,安全的URL,如下所示。
# Google Calendar
3qq6jlu04ptlhmb9fencsu5t2k
# Private
3qq6jlu04ptlhmb9fencsu5t2k
# Private 'token'
163a0afe7fkb1ba2acd04c11ef0eefe8
# LogMeIn
# 1024 bit - 128 Character URL
72oxuj0fzefqo3fu04xjtvmd0adj2948rfh7g5by4forkwcy7t651z7hcb6kjjgqkxmvmfqpyrcfy15z1fto8ewcxstjc6avicag7d5qnoimsm19kb9kgi9i7v6z01d5
我倾向于128字符,1024位样式,因为它看起来非常安全。我想我可以制作四个MD5哈希并合并它们,但这真的很有效吗?
对于这样的网址,我有两个特定的意图,但我确信还有其他人可能觉得这很有用。
1)即时登录用户的快捷方式/图标
2)一次性网址(密码恢复链接)
答案 0 :(得分:9)
更新
对于像单次使用URL这样的东西,我会使用已建议的GUID-esque appoach。确保链接的使用寿命很短。
对于即时登录,没有真正安全的方法来拥有单个URL。
是的,你可以生成一个几乎无法猜测的网址,但这并不能给你带来超级安全性。如果您想记住用户,为什么不使用加密的身份验证cookie?
您提供的示例,Google日历不会仅通过网址登录您,您必须先在网址显示之前进行身份验证。
E.g。点击我的Gmail上的谷歌日历给我:
https://www.google.com/calendar/render?tab=mc&gsessionid=-LTeHrnKoeAbDcVaN68NHA
除非您第一次以我身份验证,否则这无法帮助您访问我的帐户。
旧帖子:
您可以使用com_create _guid在PHP中生成GUID并使用它。
在linux上我认为您可以使用uuid_create或here中的此代码:
<?php
function guid(){
if (function_exists('com_create_guid')){
return com_create_guid();
}else{
mt_srand((double)microtime()*10000);//optional for php 4.2.0 and up.
$charid = strtoupper(md5(uniqid(rand(), true)));
$hyphen = chr(45);// "-"
$uuid = chr(123)// "{"
.substr($charid, 0, 8).$hyphen
.substr($charid, 8, 4).$hyphen
.substr($charid,12, 4).$hyphen
.substr($charid,16, 4).$hyphen
.substr($charid,20,12)
.chr(125);// "}"
return $uuid;
}
}
echo guid();
?>
答案 1 :(得分:9)
尝试uniqid - 并且可能与md5哈希相结合,如示例中所示:
// no prefix
// works only in PHP 5 and later versions
$token = md5(uniqid());
// better, difficult to guess
$better_token = md5(uniqid(rand(), true));
但我必须注意,没有以这种方式生成的网址(无论哈希算法是什么)都是“安全的”,很难猜测。
答案 2 :(得分:4)
只需生成一个GUID。虽然这不是旧式的顺序GUID,但这很重要。
然而,似乎php没有自己的GUID生成功能。另一个答案中建议的com_create_guid函数似乎只能在Windows上运行时才能在php中使用。
在手册页上为非Windows提供了com_create_guid的用户建议替代方法:
function guid(){
if (function_exists('com_create_guid')){
return com_create_guid();
}else{
mt_srand((double)microtime()*10000);//optional for php 4.2.0 and up.
$charid = strtoupper(md5(uniqid(rand(), true)));
$hyphen = chr(45);// "-"
$uuid = chr(123)// "{"
.substr($charid, 0, 8).$hyphen
.substr($charid, 8, 4).$hyphen
.substr($charid,12, 4).$hyphen
.substr($charid,16, 4).$hyphen
.substr($charid,20,12)
.chr(125);// "}"
return $uuid;
}
}
但我必须承认,我不愿意将它用于任何重要的事情,以防潜伏在我身上的非加密训练的头脑没有发现。
答案 3 :(得分:3)
id无法猜测,GUID是独一无二的,但并不难猜测。
你需要一个好的随机数生成器,每个加密/加密库至少有一个,我不懂PHP,所以我不能给你这个函数名。
然后你必须决定你的随机数会有多长,你应该选择一个如此之大的长度,以至于任何猜测数字的人都会得到一个未分配的数字 - 或者:
估算您必须生成的唯一网址数量,计算需要多少位来代表它们,然后将位数加倍(至少)。
或者,使用您的用户将接受的最大数量
现在您有一个“安全”号码,您可以将其转换为十进制,十六进制或base64并使用该字符串。
答案 4 :(得分:2)
我会避免这个:
1)即时登录用户的快捷方式/图标
因为这些URL可以缓存/登录代理,网络日志,浏览器缓存,书签,电子邮件等。
答案 5 :(得分:1)
修剪额外的花括号
$ guid = strtolower(trim(com_create_guid(),“{}”)); (PHP 5或更高版本)
答案 6 :(得分:1)
如果您想确保该URL既是唯一的,又只能使用有限次数:
使用以下字段保留一个小型数据库:RandomKey
,InternalURL
,Counter
,TimeStamp
从足够大的池中创建一个随机数 非顺序GUID应该足够了
将其作为RandomKey
保存在您的数据库中,以及系统处理该URL和时间戳所需的实际内部URL或资源代码。
当用户点击或输入网址时,请针对该数据库进行检查:如果TimeStamp
太旧或Counter
太高,请采取适当的措施(例如,如果您希望此URL可在有限时间或特定次数内访问。)
否则,只需使用InternalURL
处理请求,然后将结果发回给用户。
当URL已被使用或已达到其最大使用计数器时,只需将其从数据库中删除,以便不再使用它。
很高兴为您提供几乎无法猜到的一次性网址。
当然,您还必须实施一些安全检查,以限制人们尝试访问无效网址的速度。