Generating Unique Keys
Trevor Perrin
trevp at trevp.net
Tue Jan 28 15:37:21 EST 2003
>
> If you have a way of getting a unique integer (say an increasing
> sequence), a very simple way to turn it into an unguessable token is:
>
> import sha
>
> # make some secret string that's part of your server configuration
> # do NOT reveal it to attackers ;-)
> secret_prefix = "some fixed secret string--swordfish orangutan zorkmid"
>
> # and then to make a token
> token = sha.new(secret_prefix + str(unique_integer)).hexdigest()
I think that's a little iffy - SHA1 has a "length extension" property,
where if you know h(m) for some message m that's a multiple of the
block length (64 bytes in this case) you can compute h(m+x) (i.e. m
with x appended). So if one of your unique integers was a prefix of
another, and your secret_prefix was the right size, you'd be in
trouble. It would be better to use hmac-sha1 with the secret_prefix
as the key. And it would be better to generate the secret_prefix as a
good random number on system startup, not bake it into a
configuration.
As for getting a good random number on different platforms, Peter
Gutmann's cryptlib (http://www.cs.auckland.ac.nz/~pgut001/cryptlib/)
does an excellent job of this, it has systems-specific code for
windows, unix, mac, and others, and uses a randomness pool of his own
design (written up in
http://www.cs.auckland.ac.nz/~pgut001/pubs/usenix98.pdf) postprocessed
through an X9.17 generator for FIPS compliance. I don't know what all
that means, but I think it's good :-).
Anyways, I've got a python wrapper for cryptlib (in alpha state) at
http://trevp.net. Once I test it on some more systems, and maybe
implement some of the pythonic cipher interfaces, I'll announce it to
the list.
But as an example of using it to get a random key and then just
running AES in OFB mode to get a sequence of random 16-byte blocks:
>>> from cl32 import * # load the shared library
>>> from array import *
>>> cryptInit()
>>> c = cryptCreateContext(CRYPT_UNUSED, CRYPT_ALGO_AES)
>>> c.CTXINFO_MODE = CRYPT_MODE_OFB
>>> cryptGenerateKey(c)
>>> a = array('b', '\0' * 16)
>>> cryptEncrypt(c, a) # get first value
>>> doSomethingWith(a)
>>> cryptEncrypt(c, a) @ get second value
>>> cryptEncrypt(c, a) @ get third value, etc..
Trevor
More information about the Python-list
mailing list