string EncodePassword (string password, MembershipPasswordFormat passwordFormat, string salt)
{
byte [] password_bytes;
byte [] salt_bytes;
switch (passwordFormat) {
case MembershipPasswordFormat.Clear:
return password;
case MembershipPasswordFormat.Hashed:
password_bytes = Encoding.Unicode.GetBytes (password);
salt_bytes = Convert.FromBase64String (salt);
byte [] hashBytes = new byte [salt_bytes.Length + password_bytes.Length];
Buffer.BlockCopy (salt_bytes, 0, hashBytes, 0, salt_bytes.Length);
Buffer.BlockCopy (password_bytes, 0, hashBytes, salt_bytes.Length, password_bytes.Length);
MembershipSection section = (MembershipSection) WebConfigurationManager.GetSection ("system.web/membership");
string alg_type = section.HashAlgorithmType;
if (alg_type.Length == 0) {
alg_type = MachineKeySection.Config.Validation.ToString ();
#if NET_4_0
// support new (4.0) custom algorithms
if (alg_type.StartsWith ("alg:"))
alg_type = alg_type.Substring (4);
#endif
}
using (HashAlgorithm hash = HashAlgorithm.Create (alg_type)) {
#if NET_4_0
// for compatibility (with 2.0) we'll allow MD5 and SHA1 not to map to HMACMD5 and HMACSHA1
// but that won't work with new (4.0) algorithms, like HMACSHA256|384|512 or custom, won't work without using the key
KeyedHashAlgorithm kha = (hash as KeyedHashAlgorithm);
if (kha != null)
kha.Key = MachineKeySection.Config.GetValidationKey ();
#endif
hash.TransformFinalBlock (hashBytes, 0, hashBytes.Length);
return Convert.ToBase64String (hash.Hash);
}
case MembershipPasswordFormat.Encrypted:
password_bytes = Encoding.Unicode.GetBytes (password);
salt_bytes = Convert.FromBase64String (salt);
byte [] buf = new byte [password_bytes.Length + salt_bytes.Length];
Array.Copy (salt_bytes, 0, buf, 0, salt_bytes.Length);
Array.Copy (password_bytes, 0, buf, salt_bytes.Length, password_bytes.Length);
return Convert.ToBase64String (EncryptPassword (buf));
default:
/* not reached.. */
return null;
}
}