好久没写blog了,最近实在太多事情了.


大多网站基本都会有用户系统, 在经历了之前csdn的密码泄露风波之后,应该不会有人再明文存储密码了吧


一般做法是 用户表中 存储加密 之后的密码. 当用户登录 的时候 相同算法加密用户的 输入,然后比较 和数据库中加密 后的密码是否 一致来实现鉴权.

一般加密 是用md5加密


/// <summary>
/// MD5
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
private static string MD5(string password)
{
    System.Security.Cryptography.MD5CryptoServiceProvider md5 = new System.Security.Cryptography.MD5CryptoServiceProvider();
    byte[] bs = System.Text.Encoding.UTF8.GetBytes(password);
    bs = md5.ComputeHash(bs);
    System.Text.StringBuilder s = new System.Text.StringBuilder();
    foreach (byte b in bs)
    {
        s.Append(b.ToString("x2"));
    }
    return s.ToString();
}



然而,现在cmd5,彩虹表等可以实现反向 查询,简单的md5依然不够 安全

因此,大多再会加一点 调料,盐. 也就是盐值,


/// <summary>
/// MD5 Salt
/// </summary>
/// <param name="rawPass"></param>
/// <param name="salt"></param>
/// <returns></returns>
public static string MD5(string password, string salt)
{
    if (salt == null)
    {
        throw new Exception("salt is null");
    }
    return MD5(password   "{"   salt   "}");
}

当然, 盐值不是 无敌的, 但是盐值可 加大密文的 破解难度.

盐值一般 是选择一段 随机数,  最终库中存入的是 密文和盐值 本身

如果为了 省事,也可以用 userid等不会 变更的值做盐值





再记录一下对称加密

        private static string Encrypt(string input, string sKey = "ascend12", string sIV = "ascend12")
        {
            StringBuilder ret = new StringBuilder();
            using (DESCryptoServiceProvider des = new DESCryptoServiceProvider())
            {
                byte[] inputByteArray = Encoding.UTF8.GetBytes(input);
                des.Key = ASCIIEncoding.UTF8.GetBytes(sKey);
                des.IV = ASCIIEncoding.UTF8.GetBytes(sIV);

                using (MemoryStream ms = new MemoryStream())
                {
                    using (CryptoStream cs = new CryptoStream(ms, des.CreateEncryptor(), CryptoStreamMode.Write))
                    {
                        cs.Write(inputByteArray, 0, inputByteArray.Length);
                        cs.FlushFinalBlock();
                    } 
                    foreach (byte b in ms.ToArray())
                        ret.AppendFormat("{0:X2}", b);
                }
            } 
            return ret.ToString();
        }


        private static string Decrypt(string input, string sKey = "ascend12", string sIV = "ascend12")
        {
            using (DESCryptoServiceProvider des = new DESCryptoServiceProvider())
            {

                byte[] inputByteArray = new byte[input.Length / 2]; 
                for (int x = 0; x < input.Length / 2; x  )
                {
                    int i = (Convert.ToInt32(input.Substring(x * 2, 2), 16));
                    inputByteArray[x] = (byte)i;
                } 
                des.Key = ASCIIEncoding.UTF8.GetBytes(sKey);
                des.IV = ASCIIEncoding.UTF8.GetBytes(sIV);
                using (MemoryStream ms = new MemoryStream())
                {
                    using (CryptoStream cs = new CryptoStream(ms, des.CreateDecryptor(), CryptoStreamMode.Write))
                    { 
                        try
                        {
                            cs.Write(inputByteArray, 0, inputByteArray.Length);
                            cs.FlushFinalBlock(); 
                            return System.Text.Encoding.Default.GetString(ms.ToArray());
                        }
                        catch (CryptographicException)
                        { 
                            return "N/A";
                        }
                    }
                }
            }
        }



Leave a Reply