[Checkins] SVN: Zope3/trunk/ Added salt to MD5/SHA1 password managers

Dmitry Vasiliev dima at hlabs.spb.ru
Tue Apr 24 07:52:28 EDT 2007


Log message for revision 74700:
  Added salt to MD5/SHA1 password managers

Changed:
  U   Zope3/trunk/doc/CHANGES.txt
  U   Zope3/trunk/src/zope/app/authentication/password.py

-=-
Modified: Zope3/trunk/doc/CHANGES.txt
===================================================================
--- Zope3/trunk/doc/CHANGES.txt	2007-04-24 10:27:02 UTC (rev 74699)
+++ Zope3/trunk/doc/CHANGES.txt	2007-04-24 11:52:28 UTC (rev 74700)
@@ -10,6 +10,9 @@
 
     New features
 
+      - Added salt to MD5/SHA1 password managers. (Thanks Mark Giovannetti for
+        the patch)
+
       - Added field to the application control panel that displays whether
         developer mode is turned on or off.  (Also fixes #98256.)
 

Modified: Zope3/trunk/src/zope/app/authentication/password.py
===================================================================
--- Zope3/trunk/src/zope/app/authentication/password.py	2007-04-24 10:27:02 UTC (rev 74699)
+++ Zope3/trunk/src/zope/app/authentication/password.py	2007-04-24 11:52:28 UTC (rev 74700)
@@ -19,6 +19,7 @@
 
 import md5
 import sha
+from random import randint
 from codecs import getencoder
 
 from zope.interface import implements, classProvides
@@ -69,21 +70,38 @@
     True
 
     >>> password = u"right \N{CYRILLIC CAPITAL LETTER A}"
-    >>> encoded = manager.encodePassword(password)
+    >>> encoded = manager.encodePassword(password, salt="")
     >>> encoded
     '86dddccec45db4599f1ac00018e54139'
     >>> manager.checkPassword(encoded, password)
     True
     >>> manager.checkPassword(encoded, password + u"wrong")
     False
+
+    >>> encoded = manager.encodePassword(password)
+    >>> encoded[8:]
+    '86dddccec45db4599f1ac00018e54139'
+    >>> manager.checkPassword(encoded, password)
+    True
+    >>> manager.checkPassword(encoded, password + u"wrong")
+    False
+
+    >>> manager.encodePassword(password) != manager.encodePassword(password)
+    True
     """
 
     implements(IPasswordManager)
 
-    def encodePassword(self, password):
-        return md5.new(_encoder(password)[0]).hexdigest()
+    def encodePassword(self, password, salt=None):
+        if salt is None:
+            salt = "%08x" % randint(0, 0xffffffff)
+        return salt + md5.new(_encoder(password)[0]).hexdigest()
 
+    def checkPassword(self, storedPassword, password):
+        salt = storedPassword[:-32]
+        return storedPassword == self.encodePassword(password, salt)
 
+
 class SHA1PasswordManager(PlainTextPasswordManager):
     """SHA1 password manager.
 
@@ -94,21 +112,38 @@
     True
 
     >>> password = u"right \N{CYRILLIC CAPITAL LETTER A}"
-    >>> encoded = manager.encodePassword(password)
+    >>> encoded = manager.encodePassword(password, salt="")
     >>> encoded
     '04b4eec7154c5f3a2ec6d2956fb80b80dc737402'
     >>> manager.checkPassword(encoded, password)
     True
     >>> manager.checkPassword(encoded, password + u"wrong")
     False
+
+    >>> encoded = manager.encodePassword(password)
+    >>> encoded[8:]
+    '04b4eec7154c5f3a2ec6d2956fb80b80dc737402'
+    >>> manager.checkPassword(encoded, password)
+    True
+    >>> manager.checkPassword(encoded, password + u"wrong")
+    False
+
+    >>> manager.encodePassword(password) != manager.encodePassword(password)
+    True
     """
 
     implements(IPasswordManager)
 
-    def encodePassword(self, password):
-        return sha.new(_encoder(password)[0]).hexdigest()
+    def encodePassword(self, password, salt=None):
+        if salt is None:
+            salt = "%08x" % randint(0, 0xffffffff)
+        return salt + sha.new(_encoder(password)[0]).hexdigest()
 
+    def checkPassword(self, storedPassword, password):
+        salt = storedPassword[:-40]
+        return storedPassword == self.encodePassword(password, salt)
 
+
 # Simple registry used by mkzopeinstance script
 managers = [
     ("Plain Text", PlainTextPasswordManager()), # default



More information about the Checkins mailing list