【问题标题】:Generating Private, Unique, Secure URLs生成私有、唯一、安全的 URL
【发布时间】:2009-03-01 09:15:31
【问题描述】:

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

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

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

对于这样的网址,我有两个特定的意图,但我相信还有其他人可能会觉得这很有用。

1) 用户即时登录快捷方式/图标

2) 一次性网址(密码恢复链接)

【问题讨论】:

  • ...为什么?不,说真的,你为什么想要这样的 URL?听起来您正在尝试重新发明会话密钥;没有更多上下文,很难帮助您找到正确的解决方案。
  • 我想这是被标记为安全的,因为这些类型的 url 通常用于立即登录用户或重置他们的密码。它们与会话密钥不同,因为它们通常只能用于单个操作一次,而不是像会话 ID 那样可能会持续数周。
  • 我对这样的 url 有两个特定的意图,1) 用户的即时登录快捷方式/图标 2) 一次性 url(密码恢复链接)
  • 为什么不使用 cookie 进行即时登录?第二个是有道理的。

标签: php security url


【解决方案1】:

更新:

对于单次使用 URL 之类的东西,我会使用建议的 GUID 式方法。确保链接的生命周期较短。

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

是的,您可以生成一个几乎无法猜测的 URL,但这并不能为您提供超级安全性。如果您想记住用户,为什么不使用加密的身份验证 cookie?

您给出的示例,Google 日历不会单独通过 URL 登录,您必须先进行身份验证,然后 URL 才有意义。

例如从我的 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();
?>

【讨论】:

  • com_create_guid 似乎是一个仅限 Windows 的 php 函数。
  • 没错,我现在主要在 ASP.NET 上,所以我的测试服务器正在运行 windows,看起来我更新的代码和你一样。
【解决方案2】:

尝试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(无论是什么哈希算法)都不会是“安全的”,很难猜到。

【讨论】:

  • +1,UUID 是解决这些问题的方法......几乎与传统熵播种 md5 一样好。
【解决方案3】:

只需生成一个 GUID。虽然这不是旧式的顺序 GUID,但这很重要。

然而,php 似乎没有自己的 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;
    }
}

但我必须承认,我不愿意将它用于任何重要的事情,以防其中潜藏着一个我未经密码训练的大脑没有发现的不明显问题。

【讨论】:

    【解决方案4】:

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

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

    然后你必须决定你的随机数有多长,你应该选择一个足够大的长度,以至于任何猜测数字的人都会得到一个未分配的数字 - 要么:

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

    2. 或者,取用户能接受的最大数量

    现在您有了一个“安全”数字,您可以将其转换为十进制、十六进制或 base64 并使用该字符串。

    【讨论】:

    【解决方案5】:

    如果你想确保 URL 既是唯一的,又只能被使用有限的次数:

    • 保留一个包含以下字段的小型数据库:RandomKeyInternalURLCounterTimeStamp

    • 从足够大的池中创建一个随机数。
      非顺序 GUID 应该足够了

    • 将其作为RandomKey 保存在您的数据库中,以及系统处理该 URL 所需的实际内部 URL 或资源代码以及时间戳。

    • 1234563可以在有限的时间内或一定次数内访问)。
      否则,只需使用InternalURL 处理请求并将其结果发送回用户。
    • 当 URL 已被使用或已达到其最大使用计数器时,只需将其从数据库中删除,使其无法继续使用。

    很高兴为您提供几乎无法猜测的一次性 URL。

    当然,您还必须实施一些安全检查来限制人们尝试访问无效 URL 的频率。

    【讨论】:

      【解决方案6】:

      我会避免这种情况:

      1) 用户即时登录快捷方式/图标

      因为这些 URL 可以缓存/记录在代理、博客、浏览器缓存、书签、电子邮件等上。

      【讨论】:

        【解决方案7】:

        修剪额外的花括号

        $guid = strtolower(trim(com_create_guid(), "{}")); (PHP 5 或更高版本)

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2018-05-16
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-12-17
          • 1970-01-01
          相关资源
          最近更新 更多