dongmale0656 2014-04-17 06:49 采纳率: 100%
浏览 36
已采纳

Md5独特的id足以隐藏形式令牌吗?

I'm using md5(uniqid()) to generate a unique hash for my token hidden input on my forms (like Log in, Sign up, Settings, etc) for my File Sharing and Hosting service and for the user session, so I can compare those two after the form is submitted.

But I'm wondering if md5(uniqid()) is good enough after I've read that md5 has lots of security flaws.

Are there better or more secure ways of generating tokens for my forms?

Output example

<input type="hidden" name="token" value="4c1dd84d3458964ee6d59c728dc70160">
  • 写回答

4条回答 默认 最新

  • dongyuruan2957 2014-04-17 07:27
    关注

    This token should just be an unpredictable code. The best you can do to get such an unpredictable code with a deterministic computer, is to generate a really random number.

    When you use the MD5 function with your uniqid, it does not add any randomness/unpredictability to your token, you (mis)use it as an encoder. The same goal you get with using the bin2hex() function, that's what MD5 does by default after calculating the binary hash. That said, the MD5 function is not unsafe here but has no advantage neither.

    The more important point is, that the function uniqid() is not unpredictable, it is based on the current timestamp. This is the unsafe part in your code. To get an unpredictable number you can use the function mcrypt_create_iv() which reads from the random source of the operating system.

    I would recommend to let PHP create the session token for you, with the session_start() function. If you really have reasons not to use a normal PHP session, then use mcrypt_create_iv() together with an encoding function like bin2hex() or base64_encode().

    EDIT:

    From your comments i see that this token is not used to maintain the session, instead to mitigate csrf. In this case of course the session_start function won't help (the session id should not be used as csrf token), but creating an unpredictable token is still important. This is an example of how this can be done:

    /**
     * Generates a random string of a given length, using the random source of
     * the operating system. The string contains only characters of this
     * alphabet: +/0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz
     * @param int $length Number of characters the string should have.
     * @return string A random base64 encoded string.
     */
    protected static function generateRandomBase64String($length)
    {
      if (!defined('MCRYPT_DEV_URANDOM')) throw new Exception('The MCRYPT_DEV_URANDOM source is required (PHP 5.3).');
    
      // Generate random bytes, using the operating system's random source.
      // Since PHP 5.3 this also uses the random source on a Windows server.
      // Unlike /dev/random, the /dev/urandom does not block the server, if
      // there is not enough entropy available.
      $binaryLength = (int)($length * 3 / 4 + 1);
      $randomBinaryString = mcrypt_create_iv($binaryLength, MCRYPT_DEV_URANDOM);
      $randomBase64String = base64_encode($randomBinaryString);
      return substr($randomBase64String, 0, $length);
    }
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(3条)

报告相同问题?

悬赏问题

  • ¥100 set_link_state
  • ¥15 虚幻5 UE美术毛发渲染
  • ¥15 CVRP 图论 物流运输优化
  • ¥15 Tableau online 嵌入ppt失败
  • ¥100 支付宝网页转账系统不识别账号
  • ¥15 基于单片机的靶位控制系统
  • ¥15 真我手机蓝牙传输进度消息被关闭了,怎么打开?(关键词-消息通知)
  • ¥15 装 pytorch 的时候出了好多问题,遇到这种情况怎么处理?
  • ¥20 IOS游览器某宝手机网页版自动立即购买JavaScript脚本
  • ¥15 手机接入宽带网线,如何释放宽带全部速度