[Zope3-dev] SHA1Password manager, add a pinch of salt

Giovannetti, Mark giovanne at nrcan.gc.ca
Fri Apr 20 15:37:40 EDT 2007


Hi,

I've been researching authentication and whatnot in Zope 3
and was looking at the password management implementations.
I don't like the fact that the SHA1 password manager
doesn't use a random salt value when encoding and storing
a password.  Salts are commonly used in /etc/passwd and
friends to eliminate the identification of passwords that
are the same among users, as well as to make the brute
forcing space a little larger.

Here is a unified diff that adds 32 bits of salt to
the SHA1 password storage mechanism.  The same may be
done for md5, but its use is falling out of favour, so
I didn't bother.

What else do I need to do to contribute this change?
Have I missed anything?

Regards,
Mark


zope# diff -u password.py.dist password.py
--- password.py.dist    Tue Oct 24 04:21:55 2006
+++ password.py Fri Apr 20 14:21:31 2007
@@ -13,12 +13,13 @@
 ##############################################################################
 """Password managers

-$Id: password.py 70897 2006-10-24 08:21:55Z flox $
+$Id$
 """
 __docformat__ = 'restructuredtext'

 import md5
 import sha
+import random

 from zope.interface import implements, classProvides
 from zope.schema.interfaces import IVocabularyFactory
@@ -85,19 +86,34 @@
     >>> verifyObject(IPasswordManager, manager)
     True

-    >>> encoded = manager.encodePassword("password")
+    >>> encoded = manager.encodePassword("password", salt='')
     >>> encoded
     '5baa61e4c9b93f3f0682250b6cf8331b7ee68fd8'
     >>> manager.checkPassword(encoded, "password")
     True
     >>> manager.checkPassword(encoded, "bad")
     False
+
+    >>> encoded = manager.encodePassword("password")
+    >>> manager.checkPassword(encoded, "password")
+    True
+    >>> manager.checkPassword(encoded, "bad")
+    False
     """

     implements(IPasswordManager)

-    def encodePassword(self, password):
-        return sha.new(password).hexdigest()
+    def encodePassword(self, password, salt=None):
+        if salt is None:
+            salt = '%x' % random.randrange(1, 2**32-1)
+        return salt + sha.new(salt+password).hexdigest()
+
+    def checkPassword(self, storedPassword, password):
+        if len(storedPassword) == 48:
+            salt = storedPassword[0:8]
+        else:
+            salt = ''
+        return storedPassword == self.encodePassword(password, salt)

 # Simple registry used by mkzopeinstance script
 managers = [


More information about the Zope3-dev mailing list