用C# 实现 Zen Cart 的用户密码加密算法
首先看下zencart的原代码在includes\functions\password_funcs.php文件中。
////验证密码是否正确:
// This function validates a plain text password with an encrpyted password
function zen_validate_password($plain, $encrypted) {
if (zen_not_null($plain) && zen_not_null($encrypted)) {
// split apart the hash / salt
$stack = explode(':', $encrypted);
if (sizeof($stack) != 2) return false;
if (md5($stack[1] . $plain) == $stack[0]) {
return true;
}
}
return false;
}
////密码加密
// This function makes a new password from a plaintext password.
function zen_encrypt_password($plain) {
$password = '';
for ($i=0; $i<10; $i++) {
$password .= zen_rand();
}
$salt = substr(md5($password), 0, 2);
$password = md5($salt . $plain) . ':' . $salt;
return $password;
}
举个例子:
用户密码是:123456,对应的md5(UFT8 encode)值为 E10ADC3949BA59ABBE56E057F20F883E ,并且,随机数假设为 F2。
那么zencart存到数据库的密码应该为: E10ADC3949BA59ABBE56E057F20F883E:F2
这里需要强调的是,研究PHP zencart的md5函数用的encode是UTF8格式的。
这里列出C#代码的md5加密算法(encode 采用UTF8格式):
/// <summary>
/// Encrypts a string to using MD5 algorithm
/// </summary>
/// <param name="val"></param>
/// <returns>string representation of the MD5 encryption</returns>
public string EncodeToMD5String(string str)
{
// First we need to convert the string into bytes, which
// means using a text encoder.
Encoder enc = System.Text.Encoding.UTF8.GetEncoder();
// Create a buffer large enough to hold the string
byte[] unicodeText = new byte[str.Length];
enc.GetBytes(str.ToCharArray(), 0, str.Length, unicodeText, 0, true);
// Now that we have a byte array we can ask the CSP to hash it
MD5 md5 = new MD5CryptoServiceProvider();
byte[] result = md5.ComputeHash(unicodeText);
// Build the final string by converting each byte
// into hex and appending it to a StringBuilder
StringBuilder sb = new StringBuilder();
for (int i = 0; i < result.Length; i++)
{
sb.Append(result[i].ToString("X2"));//这里输出大写,要是写成x2,则输出小写
}
// And return it
return sb.ToString();
}
像这种MD5+SALT的方法,逻辑都暴露了,安全性也就这样了,增加麻烦罢了。
怎么增加安全性了,大家可以讨论下。