简单的密码验证

时间:2013-03-15 20:24:42

标签: python encryption hash passwords

我不想制作1000个密码并将其提供给用户。 密码包含6位数字 - 它们看起来像随机的6位数字。

当用户到达时,除了此密码之外没有任何信息,我想验证它。

我可以通过数据库查找此密码,但我想将此操作的难度从O(N)降低到O(1),其中N是密码的数量。

是否有任何方法可以通过简单的检查方式生成1000个“随机可能”密码?

UPD:现在我正在考虑加密。例如(Python)

key = 'top_secret'
N = 1000
passwords = [encrypt(i, key) for i in range(N)]

def check(s):
    try:
        return int(decrypt(s, key))<1000
    except ValueError:
        return False

但我想这是一个更好的解决方案

UPD2:例如,3位数和6位数。它们可能是64位和128位

4 个答案:

答案 0 :(得分:0)

使用密码作为键创建哈希。在Perl中的示例中,哈希提供恒定时间查找(O(1))。

这可能是这样的:

my %pass;

foreach ( 1 .. 1000 ) {
        # generate_next_pass() is your algorithm
        # of getting new password.
        my $p = generate_next_pass();
        $pass{$p} = 1;
}

然后O(1)检查密码是否在哈希中:

# $user_input is a password to be validated.
if ( exists $pass{$user_input} ) {
  # password correct
} else {
  # password incorrect
}

答案 1 :(得分:0)

如果密码只是 位,您可以将它们用作列表索引:

# Create a list of all possible passwords
pwds = [False for n in xrange(10**6)]
# Make 1000 valid passwords
for j in xrange(1000):
    i = random.randint(0, 10**6)
    print 'password is {:06d}'.format(i)
    pwds[i] = True

查找它们应该是O(1):

testpw = '103076'
if pwds[int(testpw)]:
    print 'Password is OK'
else:
    print 'Invalid password!'

请注意,六位数密码不是很安全。他们很容易被猜到。

更好的方法是让用户选择密码。然后存储该密码短语的SHA512哈希值作为词典的密钥,例如,用户的数据作为值。当用户给出密码时,将其哈希并查看该密钥是否在dict中。

答案 2 :(得分:0)

不是100%肯定,但您可以生成uuid4并将其存储为身份验证 - &gt;用户名查找,例如:

import uuid

userpass = {uuid.uuid4().hex:'user{:05}'.format(idx) for idx in xrange(1, 1001)}
an_item = next(iter(userpass)) # one we know is in there
for check in (an_item, 'bob'): # 'bob' we know won't be...
    print check, 'belongs to', userpass.get(check, '*nobody*')

# 8411d50aa7ec42d8a6b4736284d1837b belongs to user00381
# bob belongs to *nobody*

答案 3 :(得分:0)

由于密码很短,您可能需要使用位图。您需要1000000位= 125000字节〜= 122kB,即相当少的内存。

因此,创建一个bitmap并初始化它(完全取消设置)。生成密码并在位图中设置适当的位。用户尝试登录时检查位图。

非常重要的警告!

您在这里要做的是非常不安全

您写道,用户仅使用其密码登录,因此,无论您选择哪种数据结构来保存密码,登录系统只需要尝试猜测一个密码。由于1000存在于[0; 1000000范围内[首次尝试输入密码的概率为0,001,这是非常高值)。基本上,正如您所描述的那样,您的系统不会要求输入密码 - 它要求输入用户名。

在某些情况下,6位数的密码可能没问题,但从不使用密码作为用户名+密码。