首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >高质量、简单的随机密码生成器

高质量、简单的随机密码生成器
EN

Stack Overflow用户
提问于 2011-09-20 10:34:17
回答 18查看 100K关注 0票数 80

我感兴趣的是创建一个非常简单,高质量的随机密码生成器。有没有更好的方法来做这件事?

代码语言:javascript
复制
import os, random, string

length = 13
chars = string.ascii_letters + string.digits + '!@#$%^&*()'
random.seed = (os.urandom(1024))

print ''.join(random.choice(chars) for i in range(length))
EN

回答 18

Stack Overflow用户

发布于 2020-04-28 09:36:05

对于在2020+年遇到这个问题的任何人来说,仅供参考。Python 3.6+有一个专门用于此目的的secrets模块:

代码语言:javascript
复制
import secrets

password_length = 13
print(secrets.token_urlsafe(password_length))
票数 29
EN

Stack Overflow用户

发布于 2011-09-20 11:23:58

就在两天前,Kragen Javier Sitaker在http://lists.canonical.org/pipermail/kragen-hacks/2011-September/000527.html上发布了一个可以做到这一点的程序(现在已经不存在了--试试https://github.com/jesterpm/bin/blob/master/mkpasswd)

生成一个随机的、可记忆的密码:http://xkcd.com/936/

示例运行:

不可抗拒的克拉根:~/devel/不可抗拒-misc$ ./mkpass.py 5 12你的密码是“学习伤害保存居住阶段”。这相当于一个60位密钥。

假设对MS- 2.5e+03散列的离线攻击,这是常用的最糟糕的密码散列算法,甚至比简单的MD5还要差一点,那么这个密码将花费几年的时间才能破解我2008年的廉价赛扬E1200。

如今最常见的密码散列算法是FreeBSD的迭代MD5;破解这样的散列需要花费5.2e+06几年的时间。

但现代图形处理器的破解速度大约是其250倍,因此相同的迭代MD5将落在2e+04图形处理器数年内。

该图形处理器在2011年的运行成本约为每天1.45美元,因此破解密码的成本约为US$3e+09。

我已经开始使用这种方式生成的密码,而不是9个可打印ASCII字符的随机密码,后者同样强大。门罗关于这些密码更容易记忆的断言是正确的。然而,仍然有一个问题:因为每个字符的熵位要少得多(大约是1.7而不是6.6),所以密码中有很多冗余,所以ssh定时通道攻击( Song,Wagner和Tian Herbivore攻击,几年前的一天凌晨,我在巴格达咖啡馆从Bram Cohen那里了解到的)和键盘录音攻击等攻击更有可能捕获足够的信息,使密码可被攻击。

对于草食动物攻击,我的对策是键入字符之间有半秒延迟的密码,以便计时通道不会携带有关实际使用的字符的太多信息。此外,9个字符的密码长度较短,这就给食草动物方法提供了更少的信息。

其他可能的对策包括使用Emacs shell模式,当它识别到密码提示时,它会在本地提示您输入密码,然后立即发送整个密码,以及从其他地方复制和粘贴密码。

正如你所料,这个密码也需要更长一点的时间来输入:大约6秒,而不是大约3秒。

代码语言:javascript
复制
#!/usr/bin/python
# -*- coding: utf-8 -*-

import random, itertools, os, sys

def main(argv):
    try:
        nwords = int(argv[1])
    except IndexError:
        return usage(argv[0])

    try:
        nbits = int(argv[2])
    except IndexError:
        nbits = 11

    filename = os.path.join(os.environ['HOME'], 'devel', 'wordlist')
    wordlist = read_file(filename, nbits)
    if len(wordlist) != 2**nbits:
        sys.stderr.write("%r contains only %d words, not %d.\n" %
                         (filename, len(wordlist), 2**nbits))
        return 2

    display_password(generate_password(nwords, wordlist), nwords, nbits)
    return 0

def usage(argv0):
    p = sys.stderr.write
    p("Usage: %s nwords [nbits]\n" % argv0)
    p("Generates a password of nwords words, each with nbits bits\n")
    p("of entropy, choosing words from the first entries in\n")
    p("$HOME/devel/wordlist, which should be in the same format as\n")
    p("<http://canonical.org/~kragen/sw/wordlist>, which is a text file\n")
    p("with one word per line, preceded by its frequency, most frequent\n")
    p("words first.\n")
    p("\nRecommended:\n")
    p("    %s 5 12\n" % argv0)
    p("    %s 6\n" % argv0)
    return 1

def read_file(filename, nbits):
    return [line.split()[1] for line in
            itertools.islice(open(filename), 2**nbits)]

def generate_password(nwords, wordlist):
    choice = random.SystemRandom().choice
    return ' '.join(choice(wordlist) for ii in range(nwords))

def display_password(password, nwords, nbits):
    print 'Your password is "%s".' % password
    entropy = nwords * nbits
    print "That's equivalent to a %d-bit key." % entropy
    print

    # My Celeron E1200
    # (<http://ark.intel.com/products/34440/Intel-Celeron-Processor-E1200-(512K-Cache-1_60-GHz-800-MHz-FSB)>)
    # was released on January 20, 2008.  Running it in 32-bit mode,
    # john --test (<http://www.openwall.com/john/>) reports that it
    # can do 7303000 MD5 operations per second, but I’m pretty sure
    # that’s a single-core number (I don’t think John is
    # multithreaded) on a dual-core processor.
    t = years(entropy, 7303000 * 2)
    print "That password would take %.2g CPU-years to crack" % t
    print "on my inexpensive Celeron E1200 from 2008,"
    print "assuming an offline attack on a MS-Cache hash,"
    print "which is the worst password hashing algorithm in common use,"
    print "slightly worse than even simple MD5."
    print

    t = years(entropy, 3539 * 2)
    print "The most common password-hashing algorithm these days is FreeBSD’s"
    print "iterated MD5; cracking such a hash would take %.2g CPU-years." % t
    print

    # (As it happens, my own machines use Drepper’s SHA-2-based
    # hashing algorithm that was developed to replace the one
    # mentioned above; I am assuming that it’s at least as slow as the
    # MD5-crypt.)

    # <https://en.bitcoin.it/wiki/Mining_hardware_comparison> says a
    # Core 2 Duo U7600 can do 1.1 Mhash/s (of Bitcoin) at a 1.2GHz
    # clock with one thread.  The Celeron in my machine that I
    # benchmarked is basically a Core 2 Duo with a smaller cache, so
    # I’m going to assume that it could probably do about 1.5Mhash/s.
    # All common password-hashing algorithms (the ones mentioned
    # above, the others implemented in John, and bcrypt, but not
    # scrypt) use very little memory and, I believe, should scale on
    # GPUs comparably to the SHA-256 used in Bitcoin.

    # The same mining-hardware comparison says a Radeon 5870 card can
    # do 393.46 Mhash/s for US$350.

    print "But a modern GPU can crack about 250 times as fast,"
    print "so that same iterated MD5 would fall in %.1g GPU-years." % (t / 250)
    print

    # Suppose we depreciate the video card by Moore’s law,
    # i.e. halving in value every 18 months.  That's a loss of about
    # 0.13% in value every day; at US$350, that’s about 44¢ per day,
    # or US$160 per GPU-year.  If someone wanted your password as
    # quickly as possible, they could distribute the cracking job
    # across a network of millions of these cards.  The cards
    # additionally use about 200 watts of power, which at 16¢/kWh
    # works out to 77¢ per day.  If we assume an additional 20%
    # overhead, that’s US$1.45/day or US$529/GPU-year.
    cost_per_day = 1.45
    cost_per_crack = cost_per_day * 365 * t
    print "That GPU costs about US$%.2f per day to run in 2011," % cost_per_day
    print "so cracking the password would cost about US$%.1g." % cost_per_crack

def years(entropy, crypts_per_second):
    return float(2**entropy) / crypts_per_second / 86400 / 365.2422

if __name__ == '__main__':
    sys.exit(main(sys.argv))
票数 13
EN

Stack Overflow用户

发布于 2012-12-16 21:47:49

实现@Thomas Pornin解决方案

代码语言:javascript
复制
import M2Crypto
import string

def random_password(length=10):
    chars = string.ascii_uppercase + string.digits + string.ascii_lowercase
    password = ''
    for i in range(length):
        password += chars[ord(M2Crypto.m2.rand_bytes(1)) % len(chars)]
    return password
票数 11
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/7479442

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档