【问题标题】:Creating a salt in python在python中创建盐
【发布时间】:2011-07-14 17:13:19
【问题描述】:

如何在 python 中创建一个随机的、16 个字符的 base-62 salt?我需要它作为协议,但我不知道从哪里开始。谢谢。

【问题讨论】:

    标签: python salt base62


    【解决方案1】:

    老问题,secrets 的新解决方案

    import secrets
    
    random_string = secrets.token_hex(8)
    

    将产生一个加密强度高的 16 字符随机字符串。

    使用它而不是标准的伪随机数生成器,因为它们的安全性要低得多。

    引用secrets页面:

    secrets 模块用于生成适用于管理密码、帐户身份验证、安全令牌和相关机密等数据的加密强随机数。

    特别是,应该优先使用机密,而不是随机模块中的默认伪随机数生成器,该生成器是为建模和模拟而设计的,而不是安全或密码学。

    【讨论】:

      【解决方案2】:
      import random
      import string
      
      def get_salt(size=16, chars=None):
          if not chars:
              chars = ''.join(
                  [string.ascii_uppercase, 
                   string.ascii_lowercase, 
                   string.digits]
              )
          return ''.join(random.choice(chars) for x in range(size))
      

      【讨论】:

      • 您对“盐应该是唯一的,而不是随机的”的加盐原则有何看法?
      【解决方案3】:

      现在crypt 模块中有一个官方的mksalt 方法。 它不会为您提供简单的 16 字符长字符串,而是在大多数散列函数所需的前面添加 $digit$。如果您使用哈希密码,这可能更安全。

      import crypt
      crypt.mksalt(crypt.METHOD_SHA512)
      

      生成如下输出:

      $6$wpg9lx1sVFNFSCrP
      

      【讨论】:

      • python 2.7 中不存在
      【解决方案4】:

      您不应该使用 UUID,它们是唯一的,而不是随机的:Is using a CreateUUID() function as salt a good idea?

      你的 salts 应该使用加密安全的随机数,在 python 2.4+ 中,os.urandom 是这些的来源(如果你有一个好的计时来源)。

      # for some given b62encode function
      
      salt = b62encode(os.urandom(16))
      

      您还可以使用来自 bcrypt 的生成器或其他很棒的加密/哈希库,这些库众所周知并经过比我更专业的人的审查。

      import bcrypt
      salt = bcrypt.gensalt()
      # will be 29 chars you can then encode it however you want.
      

      【讨论】:

      • 它给了我一个错误:ImportError: No module named bcrypt
      • pip install bcrypt 应该会消除错误...表明您的计算机中没有安装 bcrypt 包 --- anurageldorado
      • 您的 base_64 示例不起作用。一个哈希值可能包含[./a-zA-Z0-9],你的哈希值还可能包含+=\n
      • @cdauth 考虑到我误读了问题的开头(要求使用 base 62),我已经更新了这个以反映这一点。我假设它们存在一个编码功能 - 很容易在 SO 上找到其中一个。
      【解决方案5】:

      在base64中:

      import random, base64, struct
      rand_float = random.SystemRandom().random()
      salt = base64.b64encode((struct.pack('!d', rand_float)))
      

      这将是 12 个字符

      【讨论】:

        【解决方案6】:

        我有点喜欢:

        import md5, uuid
        m = md5.md5()
        m.update(uuid.uuid4())
        print m.digest()[:16]
        

        这将是非常非常随机的。

        【讨论】:

        • 您的意思是m.update(str(uuid.uuid4()))?还有m.hexdigest()[:16]?但是,那不会在base62 中,对吧?
        • 对不起,你是对的代码。我想,因为我的解决方案使用了 base62 字符的一个子集,它可能适用于原始海报。
        【解决方案7】:
        >>> import random
        >>> ALPHABET = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
        >>> chars=[]
        >>> for i in range(16):
            chars.append(random.choice(ALPHABET))
        
        >>> "".join(chars)
        'wE9mg9pu2KSmp5lh'
        

        这应该可行。

        【讨论】:

        • 不错的答案,但最后 4 行只需 ''.join(random.choice(ALPHABET) for i in range(16))
        • @ScottGriffiths 我不会说它更惯用,因为它是一个单行...不过,这是一个很好的单行,太棒了:)
        • ''.join(chr(random.randint(32,126)) for i in range(16)) 怎么样?
        • 啊,对不起,不是base62。
        • 另请参阅 secrets.choice(3.6+ 版本)以获取加密安全版本,替换示例中的 random.choice。
        猜你喜欢
        • 2018-06-15
        • 1970-01-01
        • 1970-01-01
        • 2017-05-04
        • 2013-07-05
        • 2017-01-31
        • 2016-01-24
        • 2021-04-03
        • 1970-01-01
        相关资源
        最近更新 更多