在WPF应用程序中编码和解码密码

时间:2015-05-08 23:15:40

标签: c# sql wpf sha1 password-encryption

我有一个包含用户表单的WPF应用程序。我有一个我需要的密码字段,我只有一个加密方法:

public static string Encode(string value)
    {
        var hash = System.Security.Cryptography.SHA1.Create();
        var encoder = new System.Text.ASCIIEncoding();
        var combined = encoder.GetBytes(value ?? "");
        return BitConverter.ToString(hash.ComputeHash(combined)).ToLower().Replace("-", "");

    }

如何为此创建解码方法?

5 个答案:

答案 0 :(得分:1)

这种情况下的关键是您不想解密密码。您要做的是使用相同的函数加密用户输入的密码,并将结果与​​用户帐户的数据库中存储的结果进行比较。

答案 1 :(得分:1)

散列是正确的做法,但你也应该散列存储在数据库中的值并比较两个散列,如果可能的话,你不应该存储密码,即使它们是加密的。

答案 2 :(得分:1)

您应该将单向散列存储在数据库中,而不是可逆加密。用户的实际密码恰好不是您的关注,只是用户在提供密码时提供的密码与数据库中的哈希相匹配。但是,您可以加密它以便在服务器上解密传输,然后进行散列以便在数据库中进行存储。

  1. 从数据库中检索salt和哈希密码。
  2. 盐候选密码并哈希它。
  3. 比较值。

答案 3 :(得分:0)

您无法解密SHA1哈希,因为它是单向哈希。哈希不是一种可逆的操作。

在辅助类下面加密和解密字符串

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;

namespace EncryptStringSample
{
    public static class StringCipher
    {
        // This constant string is used as a "salt" value for the PasswordDeriveBytes function calls.
        // This size of the IV (in bytes) must = (keysize / 8).  Default keysize is 256, so the IV must be
        // 32 bytes long.  Using a 16 character string here gives us 32 bytes when converted to a byte array.
        private static readonly byte[] initVectorBytes = Encoding.ASCII.GetBytes("tu89geji340t89u2");

        // This constant is used to determine the keysize of the encryption algorithm.
        private const int keysize = 256;

        public static string Encrypt(string plainText, string passPhrase)
        {
            byte[] plainTextBytes = Encoding.UTF8.GetBytes(plainText);
            using (PasswordDeriveBytes password = new PasswordDeriveBytes(passPhrase, null))
            {
                byte[] keyBytes = password.GetBytes(keysize / 8);
                using (RijndaelManaged symmetricKey = new RijndaelManaged())
                {
                    symmetricKey.Mode = CipherMode.CBC;
                    using (ICryptoTransform encryptor = symmetricKey.CreateEncryptor(keyBytes, initVectorBytes))
                    {
                        using (MemoryStream memoryStream = new MemoryStream())
                        {
                            using (CryptoStream cryptoStream = new CryptoStream(memoryStream, encryptor, CryptoStreamMode.Write))
                            {
                                cryptoStream.Write(plainTextBytes, 0, plainTextBytes.Length);
                                cryptoStream.FlushFinalBlock();
                                byte[] cipherTextBytes = memoryStream.ToArray();
                                return Convert.ToBase64String(cipherTextBytes);
                            }
                        }
                    }
                }
            }
        }

        public static string Decrypt(string cipherText, string passPhrase)
        {
            byte[] cipherTextBytes = Convert.FromBase64String(cipherText);
            using(PasswordDeriveBytes password = new PasswordDeriveBytes(passPhrase, null))
            {
                byte[] keyBytes = password.GetBytes(keysize / 8);
                using(RijndaelManaged symmetricKey = new RijndaelManaged())
                {
                    symmetricKey.Mode = CipherMode.CBC;
                    using(ICryptoTransform decryptor = symmetricKey.CreateDecryptor(keyBytes, initVectorBytes))
                    {
                        using(MemoryStream memoryStream = new MemoryStream(cipherTextBytes))
                        {
                            using(CryptoStream cryptoStream = new CryptoStream(memoryStream, decryptor, CryptoStreamMode.Read))
                            {
                                byte[] plainTextBytes = new byte[cipherTextBytes.Length];
                                int decryptedByteCount = cryptoStream.Read(plainTextBytes, 0, plainTextBytes.Length);
                                return Encoding.UTF8.GetString(plainTextBytes, 0, decryptedByteCount);
                            }
                        }
                    }
                }
            }
        }
    }
}

上面的类可以非常简单地使用类似于以下的代码:

using System;
using System.Linq;

namespace EncryptStringSample
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Please enter a password to use:");
            string password = Console.ReadLine();
            Console.WriteLine("Please enter a string to encrypt:");
            string plaintext = Console.ReadLine();
            Console.WriteLine("");

            Console.WriteLine("Your encrypted string is:");
            string encryptedstring = StringCipher.Encrypt(plaintext, password);
            Console.WriteLine(encryptedstring);
            Console.WriteLine("");

            Console.WriteLine("Your decrypted string is:");
            string decryptedstring = StringCipher.Decrypt(encryptedstring, password);
            Console.WriteLine(decryptedstring);
            Console.WriteLine("");

            Console.ReadLine();
        }
    }
}

这是使用RSA解密和加密的另一种方法

用您的RSA密钥替换your_rsa_key。

 var provider = new System.Security.Cryptography.RSACryptoServiceProvider();
    provider.ImportParameters(your_rsa_key);

    var encryptedBytes = provider.Encrypt(
        System.Text.Encoding.UTF8.GetBytes("Hello World!"), true);

    string decryptedTest = System.Text.Encoding.UTF8.GetString(
        provider.Decrypt(encryptedBytes, true));

以下是关于RSA如何使用明确的例子

的良好链接

答案 4 :(得分:0)

SHA1是一个哈希函数,这意味着它基本上是单向函数,你无法获得原始内容。

如果需要恢复原始值,则应使用加密函数。 基本上有两类加密算法 - 对称和非对称加密函数。

  • symetric例如是AES
  • asymetric将是公钥/私钥加密,例如RSA

看一下这个示例:http://www.codeproject.com/Articles/10877/Public-Key-RSA-Encryption-in-C-NET