C#正确存储电子邮件密码

C#正确存储电子邮件密码,c#,encryption,serialization,cryptography,credentials,C#,Encryption,Serialization,Cryptography,Credentials,我正在创建一个消息传递应用程序,它将使用outlook帐户发送电子邮件。但是,我不确定在用户计算机上存储电子邮件密码的正确步骤。假设我有以下代码: SmtpClient SmtpServer = new SmtpClient("smtp.live.com"); var mail = new MailMessage(); mail.From = new MailAddress("youremail@hotmail.com"); mail.To.Add("to@gmail.com"); mail.S

我正在创建一个消息传递应用程序,它将使用outlook帐户发送电子邮件。但是,我不确定在用户计算机上存储电子邮件密码的正确步骤。假设我有以下代码:

SmtpClient SmtpServer = new SmtpClient("smtp.live.com");
var mail = new MailMessage();
mail.From = new MailAddress("youremail@hotmail.com");
mail.To.Add("to@gmail.com");
mail.Subject = "Test Mail - 1";
mail.IsBodyHtml = true;
string htmlBody;
htmlBody = "Write some HTML code here";
mail.Body = htmlBody;
SmtpServer.Port = 587;
SmtpServer.UseDefaultCredentials = false;
SmtpServer.Credentials = new System.Net.NetworkCredential("youremail@hotmail.com", "password");
SmtpServer.EnableSsl = true;
SmtpServer.Send(mail);
显然,我不希望“密码”在我的应用程序中存储为字符串。在用户的机器上存储密码以便我可以将其读入应用程序并将其传递给NetworkCredential构造函数的理想/正确解决方案是什么


我已经读完了,还有。第一个链接建议将其存储在文件或注册表中,但不确定如何将其存储在注册表中。如何将其正确存储在文件中?

最好的方法是序列化凭据,然后对其进行加密,然后将加密的字节写入文件。反转该过程将有助于检索数据

首先,创建一个类AES.cs

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

namespace AES_Password_Storer
{
    public static class AES
    {
        public static byte[] AES_Encrypt(byte[] bytesToBeEncrypted, byte[] passwordBytes)
    {
        byte[] encryptedBytes = null;

        // Set your salt here, change it to meet your flavor:
        // The salt bytes must be at least 8 bytes.
        byte[] saltBytes = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8 };

        using (MemoryStream ms = new MemoryStream())
        {
            using (RijndaelManaged AES = new RijndaelManaged())
            {
                AES.KeySize = 256;
                AES.BlockSize = 128;

                var key = new Rfc2898DeriveBytes(passwordBytes, saltBytes, 1000);
                AES.Key = key.GetBytes(AES.KeySize / 8);
                AES.IV = key.GetBytes(AES.BlockSize / 8);

                AES.Mode = CipherMode.CBC;

                using (var cs = new CryptoStream(ms, AES.CreateEncryptor(), CryptoStreamMode.Write))
                {
                    cs.Write(bytesToBeEncrypted, 0, bytesToBeEncrypted.Length);
                    cs.Close();
                }
                encryptedBytes = ms.ToArray();
            }
        }

        return encryptedBytes;
    }
    public static byte[] AES_Decrypt(byte[] bytesToBeDecrypted, byte[] passwordBytes)
    {
        byte[] decryptedBytes = null;

        // Set your salt here, change it to meet your flavor:
        // The salt bytes must be at least 8 bytes.
        byte[] saltBytes = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8 };

        using (MemoryStream ms = new MemoryStream())
        {
            using (RijndaelManaged AES = new RijndaelManaged())
            {
                AES.KeySize = 256;
                AES.BlockSize = 128;

                var key = new Rfc2898DeriveBytes(passwordBytes, saltBytes, 1000);
                AES.Key = key.GetBytes(AES.KeySize / 8);
                AES.IV = key.GetBytes(AES.BlockSize / 8);

                AES.Mode = CipherMode.CBC;

                using (var cs = new CryptoStream(ms, AES.CreateDecryptor(), CryptoStreamMode.Write))
                {
                    cs.Write(bytesToBeDecrypted, 0, bytesToBeDecrypted.Length);
                    cs.Close();
                }
                decryptedBytes = ms.ToArray();
            }
        }

        return decryptedBytes;
    }
}
}
接下来,创建一个类Credentials.cs:N.B.-现在我已经创建了Credentials类,以便只保存一个用户的凭据。您可以通过创建一个列表来调整它以容纳多个

[Serializable]
public class Credentials
{
public string Email { get; set; }
public string Password { get; set; }
}
接下来,对于加密(将数据写入文件):

现在,对于解密:

        MemoryStream ms = new   MemoryStream(AES.AES_Decrypt(File.ReadAllBytes("passwordfile.pwd"), Encoding.UTF8.GetBytes("encryptionkey"))); //Here goes the key
        XmlSerializer xs = new XmlSerializer(typeof(Credentials));
        Credentials c = (Credentials)xs.Deserialize(ms);
        // This 'c' contains your credentials.

现在在加密和解密代码中,有一个字符串“encryptionkey”。这是所有这一切的关键。您可以(事实上,应该)更改此设置并将其保存在安全的地方(在您的应用程序中)。

遗憾的是,加密从来都不是一个简单的主题。难以置信的复杂,但是你需要使用一些标准。此外,加密交换可能是解决这个问题的一个更好的领域。您可以将文本存储为密文,然后对文件进行加密。请记住,如果有违反,您可能要承担责任。@Greg-谢谢您的建议。将条目序列化到文件中。然后加密文件的内容。使用解密程序,然后再次反序列化它们。@Farhanam-你能提供一个例子吗?这个解决方案有效吗?
        MemoryStream ms = new   MemoryStream(AES.AES_Decrypt(File.ReadAllBytes("passwordfile.pwd"), Encoding.UTF8.GetBytes("encryptionkey"))); //Here goes the key
        XmlSerializer xs = new XmlSerializer(typeof(Credentials));
        Credentials c = (Credentials)xs.Deserialize(ms);
        // This 'c' contains your credentials.