2009-03-01 63 views
12

我想生成一个安全的一键式访问类型的URL类似于下面的例子。我将使用PHP,但这是无关的,因为我只是想了解底层概念。有些答案建议使用GUID,但我不认为这会给我一个绝对独特的安全URL,如下所示。生成专用,唯一,安全的URL

# Google Calendar 
3qq6jlu04ptlhmb9fencsu5t2k 
# Private 
3qq6jlu04ptlhmb9fencsu5t2k 
# Private 'token' 
163a0afe7fkb1ba2acd04c11ef0eefe8 
# LogMeIn 
# 1024 bit - 128 Character URL 
72oxuj0fzefqo3fu04xjtvmd0adj2948rfh7g5by4forkwcy7t651z7hcb6kjjgqkxmvmfqpyrcfy15z1fto8ewcxstjc6avicag7d5qnoimsm19kb9kgi9i7v6z01d5 

我倾向于128字符,1024位样式,因为它看起来非常安全。我想我可以制作四个MD5哈希值并合并它们,但是真的有效吗?

我有两个像这样的网址的具体意图,但我敢肯定还有其他人可能会觉得这有用。

1)即时登录用户

2)一次性使用URL(密码恢复链接)

+0

...为什么?不,严重的是,为什么你需要这样的网址?这听起来像你试图重新创建会话密钥;没有更多的上下文,很难帮助您找到正确的解决方案。 – kquinn 2009-03-01 09:27:05

+0

为什么这个标记的安全? – jmucchiello 2009-03-01 10:20:48

+0

我想这是安全的标签,因为这些类型的网址通常用于立即登录用户或重置密码。它们与会话密钥是不同的,因为它们通常只能用于一次操作,而不是像会话ID那样可能会持续数周。 – Ben 2009-03-01 12:59:33

回答

9

更新:

对于像一次性使用的网址,我会去与已提出的GUID式的appoach。确保链接上的使用寿命很短。

对于即时登录,没有真正安全的方法来拥有一个URL。

是的,你可以生成一个网址,该网址几乎不可能猜到,但这并不能给你超级安全。如果你想记住用户,为什么不使用加密的认证cookie?

您提供的示例中,Google日历不会通过URL单独登录您,您必须在URL意味着任何内容之前先进行身份验证。

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(); 
?> 
4

只是生成GUID捷径/图标。尽管这不是旧式的顺序GUID,但这很重要。

但是,它似乎没有自己的GUID生成函数。在另一个答案中建议的com_create_guid函数在Windows上运行时似乎只能在php中使用。

没有为com_create_guid手册页上都有一个用户建议的替代非Windows:

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; 
    } 
} 

但我必须承认我很不愿意使用它的任何东西重要的情况下,没有一个非显而易见的问题隐藏在我的非加密训练的思想中。

8

尝试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)); 

然而,我必须注意到,没有这种方式生成的URL(无论哈希算法如何)都将是'安全的',非常难以猜测。

2

这个id必须是不可能猜到的,GUID是唯一的,但不是很难猜到。

你需要一个好的随机数发生器,每个加密/加密库至少有一个,我不知道PHP,所以我不能给你函数名。

然后你要决定你的随机数有多长,你应该选择一个长那么大了,任何人都猜测一些会得到一个未分配号码 - 要么:

  1. 估算唯一URL的数量你将不得不生成,计算你需要多少位来表示它们,然后加倍位数(至少)。

  2. 或者采取数量最多的用户将接受

现在你有你可以将其转换为十进制,十六进制或Base64和使用该字符串“安全”号。

1

要修剪附加大括号

$ GUID =用strtolower(修剪(com_create_guid(), “{}”)); (PHP 5或更高版本)

1

如果要确保网址是唯一的,只能使用的次数有限:

  • 保持一个小型的数据库中包含的字段:RandomKeyInternalURLCounter,TimeStamp

  • 从足够大的池中创建一个随机数。
    非连续的GUID应足以

  • 保存在你的数据库为RandomKey,与您的系统来处理URL和时间戳所需要的实际内部URL或资源代码一起。

  • 当用户点击或输入一个URL,检查针对数据库:如果TimeStamp太旧或Counter太高,如果你想这个网址是在有限的访问采取适当的措施(例如时间或某个次数)。
    否则,只需使用InternalURL来处理请求并将其结果发回给用户。

  • 当URL已被使用或已达到其最大使用计数器时,只需将其从数据库中删除,以便它不能再使用。

这是很棒的给你一次性的网址,几乎不可能猜到。

当然,您还必须执行一些安全检查,以限制人们尝试访问无效URL的速度。

2

我会避免这样的:

1)即时登录用户

快捷键/图标,因为这些URL可以缓存/登录代理,博客,浏览器缓存,书签,电子邮件等