代码之家  ›  专栏  ›  技术社区  ›  Blaine

生成私有、唯一、安全的URL

  •  13
  • Blaine  · 技术社区  · 17 年前

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

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

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

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

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

    7 回复  |  直到 17 年前
        1
  •  9
  •   BrynJ    17 年前

    尝试 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
  •  9
  •   Andrew Barrett    17 年前

    更新:

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

    例如,点击我的gmail中的谷歌日历,我会得到:

    https://www.google.com/calendar/render?tab=mc&gsessionid=-LTeHrnKoeAbDcVaN68NHA

    除非你首先以我的身份进行身份验证,否则这不会帮助你访问我的帐户。

    旧职位:

    com_create _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();
    ?>
    
        3
  •  4
  •   andynormancx    17 年前

    只需生成一个GUID。重要的是,这不是一个老式的顺序GUID。

    然而,php似乎没有自己的GUID生成函数。另一个答案中建议的com_create_guid函数似乎仅在php中在Windows上运行时可用。

    有一个用户建议的替代方案 com_create_guid 对于it手册页上的非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
  •  3
  •   Nir    17 年前

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

    然后你必须决定你的随机数的长度,你应该选择一个足够大的长度,任何猜到一个数字的人都会得到一个未分配的数字-或者:

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

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

        5
  •  3
  •   Renaud Bompuis    17 年前

    如果要确保URL是唯一的,并且只能使用有限的次数,请执行以下操作:

    • RandomKey , InternalURL , Counter , TimeStamp


    • 非顺序guid应该足够了

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

    • 当用户单击或输入URL时,请对照该数据库进行检查:如果 时间戳 柜台 太高,请采取适当的措施(例如,如果您希望此URL在有限的时间内或一定的次数内可访问)。
      否则,只需使用 内部URL 并将其结果发送回用户。

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

    这是伟大的给你的一次性网址,几乎不可能猜测。

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

        6
  •  2
  •   cherouvim    17 年前

    我避免这样做是因为:

    因为这些URL可以缓存/登录到代理、网络日志、浏览器缓存、书签、电子邮件等。

        7
  •  1
  •   Ish Kumar Ish Kumar    17 年前

    修剪其他花括号的步骤

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

    推荐文章