diff --git a/IPython/lib/__init__.py b/IPython/lib/__init__.py
index 65b0ae3..dc07221 100644
--- a/IPython/lib/__init__.py
+++ b/IPython/lib/__init__.py
@@ -25,6 +25,8 @@ from IPython.lib.inputhook import (
     current_gui
 )
 
+from IPython.lib.security import passwd
+
 #-----------------------------------------------------------------------------
 # Code
 #-----------------------------------------------------------------------------
diff --git a/IPython/lib/security.py b/IPython/lib/security.py
new file mode 100644
index 0000000..2c283a8
--- /dev/null
+++ b/IPython/lib/security.py
@@ -0,0 +1,79 @@
+"""
+Password generation for the IPython notebook.
+"""
+
+import hashlib
+import random
+
+def passwd(passphrase):
+    """Generate hashed password and salt for use in notebook configuration.
+
+    Parameters
+    ----------
+    passphrase : str
+        Password to hash.
+
+    Returns
+    -------
+    hashed_passphrase : str
+        Hashed password, in the format 'hash_algorithm:salt:passphrase_hash'.
+
+    Examples
+    --------
+    In [1]: passwd('mypassword')
+    Out[1]: 'sha1:7cf3:b7d6da294ea9592a9480c8f52e63cd42cfb9dd12'
+
+    """
+    algorithm = 'sha1'
+
+    h = hashlib.new(algorithm)
+    salt = hex(int(random.getrandbits(16)))[2:]
+    h.update(passphrase + salt)
+
+    return ':'.join((algorithm, salt, h.hexdigest()))
+
+def passwd_check(hashed_passphrase, passphrase):
+    """Verify that a given passphrase matches its hashed version.
+
+    Parameters
+    ----------
+    hashed_passphrase : str
+        Hashed password, in the format returned by `passwd`.
+    passphrase : str
+        Passphrase to validate.
+
+    Returns
+    -------
+    valid : bool
+        True if the passphrase matches the hash.
+
+    Examples
+    --------
+    In [1]: from IPython.lib.security import passwd_check
+
+    In [2]: passwd_check('sha1:7cf3:b7d6da294ea9592a9480c8f52e63cd42cfb9dd12',
+       ...:              'mypassword')
+    Out[2]: True
+
+    In [3]: passwd_check('sha1:7cf3:b7d6da294ea9592a9480c8f52e63cd42cfb9dd12',
+       ...:              'anotherpassword')
+    Out[3]: False
+
+    """
+    # Algorithm and hash length
+    supported_algorithms = {'sha1': 40}
+
+    try:
+        algorithm, salt, pw_digest = hashed_passphrase.split(':', 2)
+    except (ValueError, TypeError):
+        return False
+
+    if not (algorithm in supported_algorithms and \
+            len(pw_digest) == supported_algorithms[algorithm] and \
+            len(salt) == 4):
+        return False
+
+    h = hashlib.new(algorithm)
+    h.update(passphrase + salt)
+
+    return h.hexdigest() == pw_digest
diff --git a/IPython/lib/tests/test_security.py b/IPython/lib/tests/test_security.py
new file mode 100644
index 0000000..38bad4b
--- /dev/null
+++ b/IPython/lib/tests/test_security.py
@@ -0,0 +1,21 @@
+from IPython.lib import passwd
+from IPython.lib.security import passwd_check
+import nose.tools as nt
+
+def test_passwd_structure():
+    p = passwd('passphrase')
+    algorithm, salt, hashed = p.split(':')
+    nt.assert_equals(algorithm, 'sha1')
+    nt.assert_equals(len(salt), 4)
+    nt.assert_equals(len(hashed), 40)
+
+def test_roundtrip():
+    p = passwd('passphrase')
+    nt.assert_equals(passwd_check(p, 'passphrase'), True)
+
+def test_bad():
+    p = passwd('passphrase')
+    nt.assert_equals(passwd_check(p, p), False)
+    nt.assert_equals(passwd_check(p, 'a:b:c:d'), False)
+    nt.assert_equals(passwd_check(p, 'a:b'), False)
+