0

我使用登录控制和会员 asp.net 4. 并使用 passwrod =“12345678”创建用户,我在数据库中的密码哈希是“h8A5hga0Cy93JsKxYnJl/U2AluU=”和 passwordsalt 是“UhVlqavmEX9CiKcUXkSwCw==”。

然后我将此代码用于其他项目中的哈希密码:

public string HashPassword(string pass, string salt)
    {
        byte[] bytes = Encoding.Unicode.GetBytes(pass);
        byte[] src = Encoding.Unicode.GetBytes(salt);
        byte[] dst = new byte[src.Length + bytes.Length];

        Buffer.BlockCopy(src, 0, dst, 0, src.Length);
        Buffer.BlockCopy(bytes, 0, dst, src.Length, bytes.Length);

        HashAlgorithm algorithm = HashAlgorithm.Create("SHA1");
        byte[] inArray = algorithm.ComputeHash(dst);

        return Convert.ToBase64String(inArray);
    }

private void button2_Click(object sender, EventArgs e)
    {
        textBox2.Text = HashPassword("12345678", "UhVlqavmEX9CiKcUXkSwCw==");
    }

textBox2.Text = "YM/JNwFqlL+WA3SINQp48BIxZRI="。但是 textBox2.Text != 我的密码在数据库中使用登录控制进行了哈希处理。它是“h8A5hga0Cy93JsKxYnJl/U2AluU=”。

编辑:

它是带有登录控制的算法哈希吗?

public string EncodePassword(string pass, string salt)
    {
        byte[] bytes = Encoding.Unicode.GetBytes(pass);
        byte[] src = Convert.FromBase64String(salt);
        byte[] dst = new byte[src.Length + bytes.Length];
        Buffer.BlockCopy(src, 0, dst, 0, src.Length);
        Buffer.BlockCopy(bytes, 0, dst, src.Length, bytes.Length);
        HashAlgorithm algorithm = HashAlgorithm.Create("SHA1");
        byte[] inArray = algorithm.ComputeHash(dst);
        return Convert.ToBase64String(inArray);
    }
4

3 回答 3

3

MD5 和 SHA1 不是加密算法。它们是散列算法。

这是一个单向公式。在特定字符串上运行 MD5 或 SHA1 会得到始终相同的哈希值。无法反转函数以返回原始字符串。

所以,你不能解密。

如果要加密和解密,可以使用以下方法。

public class Encryption
    {
        private const string _defaultKey = "*3ld+43j";


        public static string Encrypt(string toEncrypt, string key)
        {
            var des = new DESCryptoServiceProvider();
            var ms = new MemoryStream();

            VerifyKey(ref key);

            des.Key = HashKey(key, des.KeySize / 8);
            des.IV = HashKey(key, des.KeySize / 8);
            byte[] inputBytes = Encoding.UTF8.GetBytes(toEncrypt);

            var cs = new CryptoStream(ms, des.CreateEncryptor(), CryptoStreamMode.Write);
            cs.Write(inputBytes, 0, inputBytes.Length);
            cs.FlushFinalBlock();

            return HttpServerUtility.UrlTokenEncode(ms.ToArray());
        }

        public static string Decrypt(string toDecrypt, string key)
        {
            var des = new DESCryptoServiceProvider();
            var ms = new MemoryStream();

            VerifyKey(ref key);

            des.Key = HashKey(key, des.KeySize / 8);
            des.IV = HashKey(key, des.KeySize / 8);
            byte[] inputBytes = HttpServerUtility.UrlTokenDecode(toDecrypt);

            var cs = new CryptoStream(ms, des.CreateDecryptor(), CryptoStreamMode.Write);
            cs.Write(inputBytes, 0, inputBytes.Length);
            cs.FlushFinalBlock();

            var encoding = Encoding.UTF8;
            return encoding.GetString(ms.ToArray());

        }

        /// <summary>
        /// Make sure key is exactly 8 characters
        /// </summary>
        /// <param name="key"></param>
        private static void VerifyKey(ref string key)
        {
            if (string.IsNullOrEmpty(key)) 
                key = _defaultKey;

            key = key.Length > 8 ? key.Substring(0, 8) : key;

            if (key.Length < 8)
            {
                for (int i = key.Length; i < 8; i++)
                {
                    key += _defaultKey[i];
                }
            }
        }

        private static byte[] HashKey(string key, int length)
        {
            var sha = new SHA1CryptoServiceProvider();
            byte[] keyBytes = Encoding.UTF8.GetBytes(key);
            byte[] hash = sha.ComputeHash(keyBytes);
            byte[] truncateHash = new byte[length];
            Array.Copy(hash, 0, truncateHash, 0, length);
            return truncateHash;
        }

    }
于 2013-09-26T08:06:51.293 回答
2

尝试

private static string CreateSalt()
        {
            //Generate a cryptographic random number.
            RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider();
            byte[] buff = new byte[32];
            rng.GetBytes(buff);
            //Return a Base64 string representation of the random number.
            return Convert.ToBase64String(buff);
        }
        private static string CreatePasswordHash(string pwd, string salt)
        {
            string saltAndPwd = String.Concat(pwd, salt);
            string hashedPwd = FormsAuthentication.HashPasswordForStoringInConfigFile(saltAndPwd, "sha1");
            return hashedPwd;
        }
于 2013-09-26T07:22:35.937 回答
1

登录控件不对密码进行编码或解码。相反,这是 MembershipProvider 的工作。

这是新的ASP.Net Universal Provider使用的哈希算法。

private static string GenerateSalt()
{
    byte[] numArray = new byte[16];
    (new RNGCryptoServiceProvider()).GetBytes(numArray);
    string base64String = Convert.ToBase64String(numArray);
    return base64String;
}

private string EncodePassword(string pass, int passwordFormat, string salt)
{
    byte[] numArray;
    byte[] numArray1;
    string base64String;
    bool length = passwordFormat != 0;
    if (length)
    {
        byte[] bytes = Encoding.Unicode.GetBytes(pass);
        byte[] numArray2 = Convert.FromBase64String(salt);
        byte[] numArray3 = null;

        HashAlgorithm hashAlgorithm = HashAlgorithm.Create(Membership.HashAlgorithmType);

        if (hashAlgorithm as KeyedHashAlgorithm == null)
        {
            numArray1 = new byte[(int) numArray2.Length + (int) bytes.Length];
            Buffer.BlockCopy(numArray2, 0, numArray1, 0, (int) numArray2.Length);
            Buffer.BlockCopy(bytes, 0, numArray1, (int) numArray2.Length, (int) bytes.Length);
            numArray3 = hashAlgorithm.ComputeHash(numArray1);
        }
        else
        {
            KeyedHashAlgorithm keyedHashAlgorithm = (KeyedHashAlgorithm) hashAlgorithm;
            if (keyedHashAlgorithm.Key.Length != numArray2.Length)
            {

                if (keyedHashAlgorithm.Key.Length >= (int) numArray2.Length)
                {
                    numArray = new byte[(int) keyedHashAlgorithm.Key.Length];
                    int num = 0;
                    while (true)
                    {
                        length = num < (int) numArray.Length;
                        if (!length)
                        {
                            break;
                        }
                        int num1 = Math.Min((int) numArray2.Length, (int) numArray.Length - num);
                        Buffer.BlockCopy(numArray2, 0, numArray, num, num1);
                        num = num + num1;
                    }
                    keyedHashAlgorithm.Key = numArray;
                }
                else
                {
                    numArray = new byte[(int) keyedHashAlgorithm.Key.Length];
                    Buffer.BlockCopy(numArray2, 0, numArray, 0, (int) numArray.Length);
                    keyedHashAlgorithm.Key = numArray;
                }
            }
            else
            {
                keyedHashAlgorithm.Key = numArray2;
            }
            numArray3 = keyedHashAlgorithm.ComputeHash(bytes);
        }

        base64String = Convert.ToBase64String(numArray3);
    }
    else
    {
        base64String = pass;
    }
    return base64String;
}
于 2013-09-27T04:46:25.367 回答