Is this secure?
Steve Holden
steve at holdenweb.com
Wed Feb 24 12:59:53 EST 2010
mk wrote:
> On 2010-02-24 03:50, Paul Rubin wrote:
>> The stuff about converting 4 random bytes to a decimal string and then
>> peeling off 2 digits at a time is pretty awful, and notice that since
>> 2**32 is 4294967296, in the cases where you get 10 digits, the first
>> 2-digit pair is never higher than 42.
>
> Yikes! I didn't think about that. This is probably where (some part of)
> probability skewing comes from.
>
> Anyway, the passwords for authorized users will be copied and pasted
> from email into in the application GUI which will remember it for them,
> so they will not have to remember and type them in. So I have little in
> the way of limitations of password length - even though in *some* cases
> somebody might have to (or be ignorant enough) to retype the password
> instead of pasting it in.
>
> In that case the "diceware" approach is not necessary, even though I
> will certainly remember this approach for a case when users will have to
> remember & type the passwords in.
>
> The main application will access the data using HTTP (probably), so the
> main point is that an attacker is not able to guess passwords using
> brute force.
>
> Using A-z with 10-char password seems to provide 3 orders of magnitude
> more combinations than a-z:
>
>>>> 57 ** 10
> 362033331456891249L
>>>> 25 ** 10
> 95367431640625L
>
> Even though I'm not sure it is worth it, assuming 1000 brute-force
> guesses per second (which over the web would amount pretty much to DOS),
> this would take # days:
>
>>>> 57 ** 10 / (1000 * 3600 * 24)
> 4190200595L
>>>> 25 ** 10 / (1000 * 3600 * 24)
> 1103789L
>
> Even then I'm not getting completely uniform distribution for some reason:
>
> d 39411
> l 39376
> f 39288
> a 39275
> s 39225
> r 39172
> p 39159
> t 39073
> k 39071
> u 39064
> e 39005
> o 39005
> n 38995
> j 38993
> h 38975
> q 38958
> c 38938
> b 38906
> g 38894
> i 38847
> m 38819
> v 38712
> z 35321
> y 35228
> w 35189
> x 35075
>
> Code:
>
> import operator
>
> def gen_rand_word(n):
> with open('/dev/urandom') as f:
> return ''.join([chr(ord('a') + ord(x) % 26) for x in f.read(n)])
>
> def count_chars(chardict, word):
> for c in word:
> try:
> chardict[c] += 1
> except KeyError:
> chardict[c] = 0
>
> if __name__ == "__main__":
> chardict = {}
> for i in range(100000):
> w = gen_rand_word(10)
> count_chars(chardict, w)
> counts = list(chardict.items())
> counts.sort(key = operator.itemgetter(1), reverse = True)
> for char, count in counts:
> print char, count
>
>> I'd write your code something like this:
>>
>> nletters = 5
>>
>> def randomword(n):
>> with open('/dev/urandom') as f:
>> return ''.join([chr(ord('a')+ord(c)%26) for c in f.read(n)])
>>
>> print randomword(nletters)
>
> Aw shucks when will I learn to do the stuff in 3 lines well instead of
> 20, poorly. :-/
>
When you've got as much experience as Paul?
regards
Steve
--
Steve Holden +1 571 484 6266 +1 800 494 3119
PyCon is coming! Atlanta, Feb 2010 http://us.pycon.org/
Holden Web LLC http://www.holdenweb.com/
UPCOMING EVENTS: http://holdenweb.eventbrite.com/
More information about the Python-list
mailing list