diff --git a/constraints/constraint_history.inc b/constraints/constraint_history.inc
index 5748b0c..b76e33e 100644
--- a/constraints/constraint_history.inc
+++ b/constraints/constraint_history.inc
@@ -25,21 +25,36 @@ function password_policy_constraint_history_error($constraint) {
  * Password validation.
  */
 function password_policy_constraint_history_validate($password, $constraint, $uid) {
-  return !in_array(md5($password), _password_policy_constraint_history_old_passwords($constraint, $uid));
+  $algorithm = strtolower(variable_get('password_policy_algorithm', 'MD5'));
+  foreach (_password_policy_constraint_history_old_passwords($constraint, $uid) as $line) {
+    if (hash($algorithm, $line['salt'] . $password) == $line['pass']) {
+      return FALSE;
+    }
+  }
+//  return !in_array(md5($password), _password_policy_constraint_history_old_passwords($constraint, $uid));
+  return TRUE;
 }
 
 /**
  * Javascript portion.
  */
 function password_policy_constraint_history_js($constraint, $uid) {
-  drupal_add_js(drupal_get_path('module', 'password_policy') .'/constraints/scripts/webtoolkit.md5.js');
-  $pass = _password_policy_constraint_history_old_passwords($constraint, $uid);
+  $algorithm = variable_get('password_policy_algorithm', 'MD5');
+  drupal_add_js(drupal_get_path('module', 'password_policy') .'/constraints/scripts/webtoolkit.' . strtolower($algorithm) . '.js');
+  $salt = array();
+  $pass = array();
+  foreach (_password_policy_constraint_history_old_passwords($constraint, $uid) as $line) {
+    $salt[] = $line['salt'];
+    $pass[] = $line['pass'];
+  }
   $s = '';
   $s .= "  var num=0;\n";
+  $s .= "  var salt=new Array(\"". implode('","', $salt) ."\");\n";
   $s .= "  var pass=new Array(\"". implode('","', $pass) ."\");\n";
   $s .= "  var i;\n";
   $s .= "  for (i=0;i<pass.length;i++) {\n";
-  $s .= "    if (pass[i] == MD5(value)) {\n";
+  $s .= "    var newvalue = salt[i] + value;\n";
+  $s .= "    if (pass[i] == $algorithm(newvalue)) {\n";
   $s .= "      num=1;\n";
   $s .= "    }\n";
   $s .= "  }\n";
@@ -60,9 +75,9 @@ function _password_policy_constraint_history_old_passwords($constraint, $uid) {
   $pass = array();
   if (!empty($uid)) {
     // note that we specify a limit of the window size, but may not get that if the history isn't there.
-    $result = db_query("SELECT pass FROM {password_policy_history} WHERE uid = %d ORDER BY created DESC LIMIT %d", $uid, $constraint);
+    $result = db_query("SELECT salt, pass FROM {password_policy_history} WHERE uid = %d ORDER BY created DESC LIMIT %d", $uid, $constraint);
     while ($row = db_fetch_array($result)) {
-      $pass[] = $row['pass'];
+      $pass[] = array('salt' => $row['salt'], 'pass' => $row['pass']);
     }
   }
   return $pass;
diff --git a/constraints/scripts/webtoolkit.sha256.js b/constraints/scripts/webtoolkit.sha256.js
new file mode 100644
index 0000000..a4d1075
--- /dev/null
+++ b/constraints/scripts/webtoolkit.sha256.js
@@ -0,0 +1,127 @@
+/**
+*
+*  Secure Hash Algorithm (SHA256)
+*  http://www.webtoolkit.info/
+*
+*  Original code by Angel Marin, Paul Johnston.
+*
+**/
+ 
+function SHA256(s){
+ 
+	var chrsz   = 8;
+	var hexcase = 0;
+ 
+	function safe_add (x, y) {
+		var lsw = (x & 0xFFFF) + (y & 0xFFFF);
+		var msw = (x >> 16) + (y >> 16) + (lsw >> 16);
+		return (msw << 16) | (lsw & 0xFFFF);
+	}
+ 
+	function S (X, n) { return ( X >>> n ) | (X << (32 - n)); }
+	function R (X, n) { return ( X >>> n ); }
+	function Ch(x, y, z) { return ((x & y) ^ ((~x) & z)); }
+	function Maj(x, y, z) { return ((x & y) ^ (x & z) ^ (y & z)); }
+	function Sigma0256(x) { return (S(x, 2) ^ S(x, 13) ^ S(x, 22)); }
+	function Sigma1256(x) { return (S(x, 6) ^ S(x, 11) ^ S(x, 25)); }
+	function Gamma0256(x) { return (S(x, 7) ^ S(x, 18) ^ R(x, 3)); }
+	function Gamma1256(x) { return (S(x, 17) ^ S(x, 19) ^ R(x, 10)); }
+ 
+	function core_sha256 (m, l) {
+		var K = new Array(0x428A2F98, 0x71374491, 0xB5C0FBCF, 0xE9B5DBA5, 0x3956C25B, 0x59F111F1, 0x923F82A4, 0xAB1C5ED5, 0xD807AA98, 0x12835B01, 0x243185BE, 0x550C7DC3, 0x72BE5D74, 0x80DEB1FE, 0x9BDC06A7, 0xC19BF174, 0xE49B69C1, 0xEFBE4786, 0xFC19DC6, 0x240CA1CC, 0x2DE92C6F, 0x4A7484AA, 0x5CB0A9DC, 0x76F988DA, 0x983E5152, 0xA831C66D, 0xB00327C8, 0xBF597FC7, 0xC6E00BF3, 0xD5A79147, 0x6CA6351, 0x14292967, 0x27B70A85, 0x2E1B2138, 0x4D2C6DFC, 0x53380D13, 0x650A7354, 0x766A0ABB, 0x81C2C92E, 0x92722C85, 0xA2BFE8A1, 0xA81A664B, 0xC24B8B70, 0xC76C51A3, 0xD192E819, 0xD6990624, 0xF40E3585, 0x106AA070, 0x19A4C116, 0x1E376C08, 0x2748774C, 0x34B0BCB5, 0x391C0CB3, 0x4ED8AA4A, 0x5B9CCA4F, 0x682E6FF3, 0x748F82EE, 0x78A5636F, 0x84C87814, 0x8CC70208, 0x90BEFFFA, 0xA4506CEB, 0xBEF9A3F7, 0xC67178F2);
+		var HASH = new Array(0x6A09E667, 0xBB67AE85, 0x3C6EF372, 0xA54FF53A, 0x510E527F, 0x9B05688C, 0x1F83D9AB, 0x5BE0CD19);
+		var W = new Array(64);
+		var a, b, c, d, e, f, g, h, i, j;
+		var T1, T2;
+ 
+		m[l >> 5] |= 0x80 << (24 - l % 32);
+		m[((l + 64 >> 9) << 4) + 15] = l;
+ 
+		for ( var i = 0; i<m.length; i+=16 ) {
+			a = HASH[0];
+			b = HASH[1];
+			c = HASH[2];
+			d = HASH[3];
+			e = HASH[4];
+			f = HASH[5];
+			g = HASH[6];
+			h = HASH[7];
+ 
+			for ( var j = 0; j<64; j++) {
+				if (j < 16) W[j] = m[j + i];
+				else W[j] = safe_add(safe_add(safe_add(Gamma1256(W[j - 2]), W[j - 7]), Gamma0256(W[j - 15])), W[j - 16]);
+ 
+				T1 = safe_add(safe_add(safe_add(safe_add(h, Sigma1256(e)), Ch(e, f, g)), K[j]), W[j]);
+				T2 = safe_add(Sigma0256(a), Maj(a, b, c));
+ 
+				h = g;
+				g = f;
+				f = e;
+				e = safe_add(d, T1);
+				d = c;
+				c = b;
+				b = a;
+				a = safe_add(T1, T2);
+			}
+ 
+			HASH[0] = safe_add(a, HASH[0]);
+			HASH[1] = safe_add(b, HASH[1]);
+			HASH[2] = safe_add(c, HASH[2]);
+			HASH[3] = safe_add(d, HASH[3]);
+			HASH[4] = safe_add(e, HASH[4]);
+			HASH[5] = safe_add(f, HASH[5]);
+			HASH[6] = safe_add(g, HASH[6]);
+			HASH[7] = safe_add(h, HASH[7]);
+		}
+		return HASH;
+	}
+ 
+	function str2binb (str) {
+		var bin = Array();
+		var mask = (1 << chrsz) - 1;
+		for(var i = 0; i < str.length * chrsz; i += chrsz) {
+			bin[i>>5] |= (str.charCodeAt(i / chrsz) & mask) << (24 - i%32);
+		}
+		return bin;
+	}
+ 
+	function Utf8Encode(string) {
+		string = string.replace(/\r\n/g,"\n");
+		var utftext = "";
+ 
+		for (var n = 0; n < string.length; n++) {
+ 
+			var c = string.charCodeAt(n);
+ 
+			if (c < 128) {
+				utftext += String.fromCharCode(c);
+			}
+			else if((c > 127) && (c < 2048)) {
+				utftext += String.fromCharCode((c >> 6) | 192);
+				utftext += String.fromCharCode((c & 63) | 128);
+			}
+			else {
+				utftext += String.fromCharCode((c >> 12) | 224);
+				utftext += String.fromCharCode(((c >> 6) & 63) | 128);
+				utftext += String.fromCharCode((c & 63) | 128);
+			}
+ 
+		}
+ 
+		return utftext;
+	}
+ 
+	function binb2hex (binarray) {
+		var hex_tab = hexcase ? "0123456789ABCDEF" : "0123456789abcdef";
+		var str = "";
+		for(var i = 0; i < binarray.length * 4; i++) {
+			str += hex_tab.charAt((binarray[i>>2] >> ((3 - i%4)*8+4)) & 0xF) +
+			hex_tab.charAt((binarray[i>>2] >> ((3 - i%4)*8  )) & 0xF);
+		}
+		return str;
+	}
+ 
+	s = Utf8Encode(s);
+	return binb2hex(core_sha256(str2binb(s), s.length * chrsz));
+ 
+}
\ No newline at end of file
diff --git a/password_policy.admin.inc b/password_policy.admin.inc
index 4f25be6..be6e531 100644
--- a/password_policy.admin.inc
+++ b/password_policy.admin.inc
@@ -51,6 +51,21 @@ function password_policy_admin_settings() {
     '#description' => t('Should password restrictions be listed on the password change page. A javascript warning block will be shown anyways if ithe typed in password does not meet the restrictions.'),
   );
 
+  // Password hash settings
+  $form['hash'] = array(
+    '#type' => 'fieldset',
+    '#title' => t('Password hash settings'),
+    '#collapsible' => TRUE,
+    '#collapsed' => FALSE
+  );
+  $form['hash']['password_policy_algorithm'] = array(
+    '#type' => 'select',
+    '#title' => t('Preferred algorithm'),
+    '#default_value' => variable_get('password_policy_algorithm', 'MD5'),
+    '#options' => array('MD5' => 'MD5', 'SHA256' => 'SHA256'),
+    '#description' => t('Select the algorithm you would like to use to hash passwords in the database.'),
+  );
+
   // E-mail notification settings.
   $form['email'] = array(
     '#type' => 'fieldset',
@@ -95,6 +110,7 @@ function password_policy_admin_settings_submit($form, &$form_state) {
       variable_set('password_policy_admin', $form_state['values']['password_policy_admin']);
       variable_set('password_policy_begin', $form_state['values']['password_policy_begin']);
       variable_set('password_policy_block', $form_state['values']['password_policy_block']);
+      variable_set('password_policy_algorithm', $form_state['values']['password_policy_algorithm']);
       variable_set('password_policy_show_restrictions', $form_state['values']['password_policy_show_restrictions']);
       variable_set('password_policy_warning_subject', $form_state['values']['password_policy_warning_subject']);
       variable_set('password_policy_warning_body', $form_state['values']['password_policy_warning_body']);
@@ -104,6 +120,7 @@ function password_policy_admin_settings_submit($form, &$form_state) {
       variable_del('password_policy_admin');
       variable_del('password_policy_begin');
       variable_del('password_policy_block');
+      variable_del('password_policy_algorithm');
       variable_del('password_policy_show_restrictions');
       variable_del('password_policy_warning_subject');
       variable_del('password_policy_warning_body');
diff --git a/password_policy.install b/password_policy.install
index ab1b2fb..dbd8f31 100644
--- a/password_policy.install
+++ b/password_policy.install
@@ -104,10 +104,16 @@ function password_policy_schema() {
           'type' => 'int',
           'not null' => TRUE,
         ),
+        'salt' => array(
+          'description' => t("A random salt value used for the password hash."),
+          'type' => 'varchar',
+          'length' => 64,
+          'not null' => TRUE,
+        ),
         'pass' => array(
-          'description' => t("User's password (md5 hash)."),
+          'description' => t("User's password hash."),
           'type' => 'varchar',
-          'length' => 32,
+          'length' => 64,
           'not null' => TRUE,
         ),
         'created' => array(
@@ -236,6 +242,7 @@ function password_policy_uninstall() {
   variable_del('password_policy_admin');
   variable_del('password_policy_begin');
   variable_del('password_policy_block');
+  variable_del('password_policy_algorithm');
   variable_del('password_policy_show_restrictions');
   variable_del('password_policy_warning_subject');
   variable_del('password_policy_warning_body');
@@ -354,3 +361,25 @@ function password_policy_update_6006() {
   db_add_unique_key($ret, 'password_policy_role','name', array('rid','name'));
   return $ret;
 }
+
+/**
+ * Changes to allow for greater security through better hashing algorithms.
+ */
+function password_policy_update_6007() {
+  $ret = array();
+  db_add_field(&$ret, 'password_policy_history', 'salt', array(
+    'description' => t("Unique salt value used for this password hash."),
+    'type' => 'varchar',
+    'length' => 64,
+    'not null' => TRUE,
+    'default' => '',
+  ));
+  db_change_field(&$ret, 'password_policy_history', 'pass', 'pass', array(
+    'description' => t("User's password hash."),
+    'type' => 'varchar',
+    'length' => 64,
+    'not null' => TRUE,
+    'default' => '',
+  ));
+  return $ret;
+}
diff --git a/password_policy.module b/password_policy.module
index f275785..1eee423 100644
--- a/password_policy.module
+++ b/password_policy.module
@@ -818,7 +818,9 @@ function _password_policy_load_active_policy($roles) {
  *   Clear text password.
  */
 function _password_policy_store_password($uid, $pass) {
-  db_query("INSERT INTO {password_policy_history} (uid, pass, created) VALUES (%d, '%s', %d)", $uid, md5($pass), time());
+  $algorithm = strtolower(variable_get('password_policy_algorithm', 'MD5'));
+  $salt = _password_policy_salt();
+  db_query("INSERT INTO {password_policy_history} (uid, salt, pass, created) VALUES (%d, '%s', '%s', %d)", $uid, $salt, hash($algorithm, $salt . $pass), time());
 }
 
 /**
@@ -871,6 +873,23 @@ function _password_policy_unblock($account) {
 }
 
 /**
+ * Internal function to create a random salt value.
+ * The random strings will be prepended to user passwords before hashing
+ * and will be stored in the password_policy_history table to allow for
+ * password comparison.
+ * 
+ * @return string
+ */
+function _password_policy_salt() {
+  $chars = 'abcdefghijklmnopgrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890';
+  $salt = '';
+  for ($i = 0; $i < 64; $i++) {
+    $salt .= $chars[mt_rand(0, strlen($chars))];
+  }
+  return $salt;
+}
+
+/**
  * Add password policy JS
  *
  * @param $policy
