[Checkins] SVN: zope.app.authentication/branches/ulif-saltfix/src/zope/app/authentication/password.py Let password managers encode passwords using a prefix in curly braces specifying the kind of encoding.
Uli Fouquet
uli at gnufix.de
Wed Jan 21 08:45:17 EST 2009
Log message for revision 94901:
Let password managers encode passwords using a prefix in curly braces specifying the kind of encoding.
Changed:
U zope.app.authentication/branches/ulif-saltfix/src/zope/app/authentication/password.py
-=-
Modified: zope.app.authentication/branches/ulif-saltfix/src/zope/app/authentication/password.py
===================================================================
--- zope.app.authentication/branches/ulif-saltfix/src/zope/app/authentication/password.py 2009-01-21 13:16:55 UTC (rev 94900)
+++ zope.app.authentication/branches/ulif-saltfix/src/zope/app/authentication/password.py 2009-01-21 13:45:17 UTC (rev 94901)
@@ -71,6 +71,9 @@
class MD5PasswordManager(PlainTextPasswordManager):
"""MD5 password manager.
+ Note: use of salt in this password manager is purely
+ cosmetical. Use SSHA if you want increased security.
+
>>> from zope.interface.verify import verifyObject
>>> manager = MD5PasswordManager()
@@ -80,7 +83,7 @@
>>> password = u"right \N{CYRILLIC CAPITAL LETTER A}"
>>> encoded = manager.encodePassword(password, salt="")
>>> encoded
- '86dddccec45db4599f1ac00018e54139'
+ '{MD5}86dddccec45db4599f1ac00018e54139'
>>> manager.checkPassword(encoded, password)
True
>>> manager.checkPassword(encoded, password + u"wrong")
@@ -103,16 +106,22 @@
def encodePassword(self, password, salt=None):
if salt is None:
salt = "%08x" % randint(0, 0xffffffff)
- return salt + md5(_encoder(password)[0]).hexdigest()
+ return '{MD5}%s%s' % (salt, md5(_encoder(password)[0]).hexdigest())
def checkPassword(self, storedPassword, password):
+ if storedPassword.startswith('{MD5}'):
+ salt = storedPassword[5:-32]
+ return storedPassword == self.encodePassword(password, salt)
salt = storedPassword[:-32]
- return storedPassword == self.encodePassword(password, salt)
+ return storedPassword == self.encodePassword(password, salt)[6:]
class SHA1PasswordManager(PlainTextPasswordManager):
"""SHA1 password manager.
+ Note: use of salt in this password manager is purely
+ cosmetical. Use SSHA if you want increased security.
+
>>> from zope.interface.verify import verifyObject
>>> manager = SHA1PasswordManager()
@@ -122,7 +131,7 @@
>>> password = u"right \N{CYRILLIC CAPITAL LETTER A}"
>>> encoded = manager.encodePassword(password, salt="")
>>> encoded
- '04b4eec7154c5f3a2ec6d2956fb80b80dc737402'
+ '{SHA1}04b4eec7154c5f3a2ec6d2956fb80b80dc737402'
>>> manager.checkPassword(encoded, password)
True
>>> manager.checkPassword(encoded, password + u"wrong")
@@ -145,15 +154,26 @@
def encodePassword(self, password, salt=None):
if salt is None:
salt = "%08x" % randint(0, 0xffffffff)
- return salt + sha1(_encoder(password)[0]).hexdigest()
+ return '{SHA1}%s%s' % (salt, sha1(_encoder(password)[0]).hexdigest())
def checkPassword(self, storedPassword, password):
+ if storedPassword.startswith('{SHA1}'):
+ salt = storedPassword[6:-40]
+ return storedPassword == self.encodePassword(password, salt)
salt = storedPassword[:-40]
- return storedPassword == self.encodePassword(password, salt)
+ return storedPassword == self.encodePassword(password, salt)[7:]
class SSHAPasswordManager(PlainTextPasswordManager):
"""SSHA password manager.
+ SSHA is basically SHA1-encoding which also incorporates a salt
+ into the encoded string. This way, stored passwords are more
+ robust against dictionary attacks of attackers that could get
+ access to lists of encoded passwords.
+
+ SSHA is regularly used in LDAP databases and we should be
+ compatible with passwords used there.
+
>>> from zope.interface.verify import verifyObject
>>> manager = SSHAPasswordManager()
More information about the Checkins
mailing list