diff --git a/contrib/htdigest.py b/contrib/htdigest.py
--- a/contrib/htdigest.py
+++ b/contrib/htdigest.py
@@ -17,10 +17,15 @@
 
 import errno
 import fileinput
-import md5
 import sys
 from optparse import OptionParser
 from getpass import getpass
+
+# The md5 module is deprecated in Python 2.5
+try:
+    from hashlib import md5
+except ImportError:
+    from md5 import md5
 
 def ask_pass():
     pass1 = getpass('New password: ')
@@ -36,7 +41,7 @@
     return make_digest(userprefix, password)
 
 def make_digest(userprefix, password):
-    return userprefix + md5.new(userprefix + password).hexdigest()
+    return userprefix + md5(userprefix + password).hexdigest()
 
 usage = "%prog [-c] [-b] passwordfile realm username"
 parser = OptionParser(usage=usage)
diff --git a/trac/ticket/notification.py b/trac/ticket/notification.py
--- a/trac/ticket/notification.py
+++ b/trac/ticket/notification.py
@@ -16,12 +16,11 @@
 # Author: Daniel Lundin <daniel@edgewall.com>
 #
 
-import md5
-
 from trac import __version__
 from trac.core import *
 from trac.config import *
 from trac.notification import NotifyEmail
+from trac.util import md5
 from trac.util.datefmt import to_timestamp
 from trac.util.text import CRLF, wrap, to_unicode
 
@@ -284,7 +283,7 @@
         s = '%s.%08d.%d.%s' % (self.config.get('project', 'url'),
                                int(self.ticket.id), to_timestamp(modtime),
                                rcpt.encode('ascii', 'ignore'))
-        dig = md5.new(s).hexdigest()
+        dig = md5(s).hexdigest()
         host = self.from_email[self.from_email.find('@') + 1:]
         msgid = '<%03d.%s@%s>' % (len(s), dig, host)
         return msgid
diff --git a/trac/util/__init__.py b/trac/util/__init__.py
--- a/trac/util/__init__.py
+++ b/trac/util/__init__.py
@@ -18,7 +18,6 @@
 #         Matthew Good <trac@matt-good.net>
 
 import locale
-import md5
 import os
 import re
 import sys
@@ -26,6 +25,12 @@
 import tempfile
 from urllib import quote, unquote, urlencode
 from itertools import izip
+
+# The md5 module is deprecated in Python 2.5
+try:
+    from hashlib import md5
+except ImportError:
+    from md5 import md5
 
 # Imports for backward compatibility
 from trac.core import TracError
@@ -271,11 +276,10 @@
     # /* The password first, since that is what is most unknown */
     # /* Then our magic string */
     # /* Then the raw salt */
-    m = md5.new()
-    m.update(password + magic + salt)
+    m = md5(password + magic + salt)
 
     # /* Then just as many characters of the MD5(pw,salt,pw) */
-    mixin = md5.md5(password + salt + password).digest()
+    mixin = md5(password + salt + password).digest()
     for i in range(0, len(password)):
         m.update(mixin[i % 16])
 
@@ -293,7 +297,7 @@
 
     # /* and now, just to make sure things don't run too fast */
     for i in range(1000):
-        m2 = md5.md5()
+        m2 = md5()
         if i & 1:
             m2.update(password)
         else:
diff --git a/trac/web/api.py b/trac/web/api.py
--- a/trac/web/api.py
+++ b/trac/web/api.py
@@ -26,7 +26,7 @@
 import urlparse
 
 from trac.core import Interface, TracError
-from trac.util import get_last_traceback
+from trac.util import get_last_traceback, md5
 from trac.util.datefmt import http_date, localtz
 from trac.web.href import Href
 from trac.web.wsgi import _FileWrapper
@@ -244,8 +244,7 @@
         so that consecutive requests can be cached.
         """
         if isinstance(extra, list):
-            import md5
-            m = md5.new()
+            m = md5()
             for elt in extra:
                 m.update(repr(elt))
             extra = m.hexdigest()
diff --git a/trac/web/auth.py b/trac/web/auth.py
--- a/trac/web/auth.py
+++ b/trac/web/auth.py
@@ -22,7 +22,6 @@
     import threading
 except ImportError:
     import dummy_threading as threading
-import md5
 import os
 import re
 import sys
@@ -35,7 +34,7 @@
 from trac.core import *
 from trac.web.api import IAuthenticator, IRequestHandler
 from trac.web.chrome import INavigationContributor
-from trac.util import hex_entropy, md5crypt
+from trac.util import hex_entropy, md5, md5crypt
 
 
 class LoginModule(Component):
@@ -367,7 +366,7 @@
             self.send_auth_request(environ, start_response)
             return None
 
-        kd = lambda x: md5.md5(':'.join(x)).hexdigest()
+        kd = lambda x: md5(':'.join(x)).hexdigest()
         a1 = self.hash[auth['username']]
         a2 = kd([environ['REQUEST_METHOD'], auth['uri']])
         # Is the response correct?

