简体   繁体   English

在将 class 保存到 xml 文件之前加密属性

[英]Encrypting properties before saving class to xml file

I am attempting to save a few pieces of the connection string as encrypted text to an XML from my class.我正在尝试将一些连接字符串作为加密文本从我的 class 保存到 XML。

Here is my class:这是我的 class:

using System.Data.SqlClient;
using TechGuyComputing.CompleteOrganizerWPF.Data;

namespace TechGuyComputing.CompleteOrganizerWPF.MiscClasses
{
  public class AppSetting
  {
    private string _dataSource;
    private string _intitialCatalog;
    private string _userId;
    private string _password;

    public string DataSource
    {
      set => _dataSource = Encryption.SimpleEncryptWithPassword(value, GlobalConstants.EncryptionPassword);
      get => Encryption.SimpleDecryptWithPassword(_dataSource, GlobalConstants.EncryptionPassword);
    }

    public string IntitialCatalog
    {
      set => _intitialCatalog = Encryption.SimpleEncryptWithPassword(value, GlobalConstants.EncryptionPassword);
      get => Encryption.SimpleDecryptWithPassword(_intitialCatalog, GlobalConstants.EncryptionPassword);
    }

    public string UserId
    {
      set => _userId = Encryption.SimpleEncryptWithPassword(value, GlobalConstants.EncryptionPassword);
      get => Encryption.SimpleDecryptWithPassword(_userId, GlobalConstants.EncryptionPassword);
    }

    public string Password
    {
      set => _password = Encryption.SimpleEncryptWithPassword(value, GlobalConstants.EncryptionPassword);
      get => Encryption.SimpleDecryptWithPassword(_password, GlobalConstants.EncryptionPassword);
    }

    public bool IntegratedSecurity { set; get; }
    public bool MultipleActiveResultSets { set; get; }
    public bool PersistSecurityInfo { set; get; }
  }

  internal static class AppSettings
  {
    public static AppSetting ApplicationSettings;

    public static SqlConnection ConnectionString { get; private set; }


    static AppSettings()
    {
      if (ApplicationSettings == null)
      {
        ApplicationSettings = XmlReader.GetAppSettingsFromXmlFile();
        SetConnectionString();
      }
    }

    public static void SaveAppSettings()
    {
      if (ApplicationSettings == null)
      {
        ApplicationSettings = new AppSetting();
      }
      XmlReader.WriteAppSettingsToXmlFile(ApplicationSettings);
      SetConnectionString();
    }

    private static void SetConnectionString()
    {
      if (string.IsNullOrEmpty(ApplicationSettings.DataSource) || string.IsNullOrEmpty(ApplicationSettings.IntitialCatalog))
      {
        ConnectionString = new SqlConnection();
        return;
      }

      var builder = new SqlConnectionStringBuilder
      {
        DataSource = ApplicationSettings.DataSource,
        InitialCatalog = ApplicationSettings.IntitialCatalog,
        IntegratedSecurity = ApplicationSettings.IntegratedSecurity,
        MultipleActiveResultSets = ApplicationSettings.MultipleActiveResultSets,
        PersistSecurityInfo = ApplicationSettings.PersistSecurityInfo,
        UserID = ApplicationSettings.UserId,
        Password = ApplicationSettings.Password
      };

      ConnectionString = new SqlConnection(builder.ConnectionString);
    }

  }
}

And this is how I am saving the XML file:这就是我保存 XML 文件的方式:

using System.IO;
using System.Xml.Serialization;

namespace TechGuyComputing.CompleteOrganizerWPF.MiscClasses
{
  internal static class XmlReader
  {

    public static void WriteAppSettingsToXmlFile(AppSetting appSetting)
    {
      var xs = new XmlSerializer(typeof(AppSetting));
      var tw = new StreamWriter(GlobalConstants.XmlFile);
      xs.Serialize(tw, appSetting);
    }

    public static AppSetting GetAppSettingsFromXmlFile()
    {
      if (!File.Exists(GlobalConstants.XmlFile))
      {
        return new AppSetting();
      }

      using (var sr = new StreamReader(GlobalConstants.XmlFile))
      {
        XmlSerializer xs = new XmlSerializer(typeof(AppSetting));
        return (AppSetting)xs.Deserialize(sr);
      }
    }


  }
}

My save is working perfectly but it is not saving the values as encrypted strings.我的保存工作正常,但它没有将值保存为加密字符串。

I thought this would handle it on the fly but it's not doing anything:我认为这会即时处理它,但它什么也没做:

public string DataSource
{
  set => _dataSource = Encryption.SimpleEncryptWithPassword(value, GlobalConstants.EncryptionPassword);
  get => Encryption.SimpleDecryptWithPassword(_dataSource, GlobalConstants.EncryptionPassword);
}

I am not getting any error messages, it's just not encrypting the data.我没有收到任何错误消息,只是没有加密数据。

Any suggestions how I encrypt certain properties before they are saved?有什么建议我如何在保存某些属性之前对其进行加密?

EDIT: I'd prefer not to encrypt the entire file if I can prevent it.编辑:如果我能阻止它,我宁愿不加密整个文件。 I would like to only encrypt the properties that I choose.我只想加密我选择的属性。

Your problem is that XmlSerializer serializes only public properties and fields -- and the public properties in your AppSetting class are all unencrypted.您的问题是XmlSerializer仅序列化公共属性和字段 - 并且AppSetting class 中的公共属性都是未加密的。 From the docs文档

XML serialization serializes only the public fields and property values of an object into an XML stream. XML 序列化仅将 object 的公共字段和属性值序列化为 XML ZF7B44CFAFD5C5222E23D7B6489。 ... ...

XML serialization does not convert methods, indexers, private fields, or read-only properties (except read-only collections). XML 序列化不会转换方法、索引器、私有字段或只读属性(只读集合除外)。 To serialize all an object's fields and properties, both public and private, use the DataContractSerializer instead of XML serialization.要序列化对象的所有字段和属性,包括公共的和私有的,请使用DataContractSerializer而不是 XML 序列化。

Thus your options are:因此,您的选择是:

  1. Make public properties for the encrypted members and mark the plaintext properties with XmlIgnore like so:为加密成员创建公共属性并使用XmlIgnore标记明文属性,如下所示:

     [System.ComponentModel.Browsable(false), System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never), System.Diagnostics.DebuggerBrowsable(System.Diagnostics.DebuggerBrowsableState.Never)] [XmlElement("DataSource")] // Optionally change the element name to be <DataSource> public string EncryptedDataSource { get; set; } [XmlIgnore] public string DataSource { set => EncryptedDataSource = Encryption.SimpleEncryptWithPassword(value, GlobalConstants.EncryptionPassword); get => Encryption.SimpleDecryptWithPassword(EncryptedDataSource, GlobalConstants.EncryptionPassword); }

    Demo fiddle #1 here .演示小提琴#1在这里

  2. Switch to DataContractSerializer .切换到DataContractSerializer First modify your class as follows:首先修改你的 class 如下:

     [DataContract] public class AppSetting { [DataMember(Name = "DataSource")] private string _dataSource; [DataMember(Name = "IntitialCatalog")] private string _intitialCatalog; [DataMember(Name = "UserId")] private string _userId; [DataMember(Name = "Password")] private string _password; // Remainder unchanged

    Then modify XmlReader as follows:然后修改XmlReader如下:

     public static void WriteAppSettingsToXmlFile(AppSetting appSetting) { var serializer = new DataContractSerializer(typeof(AppSetting)); using (var stream = new FileStream(GlobalConstants.XmlFile, FileMode.Create)) { serializer.WriteObject(stream, appSetting); } } public static AppSetting GetAppSettingsFromXmlFile() { if (.File.Exists(GlobalConstants;XmlFile)) { return new AppSetting(). } using (var stream = File.OpenRead(GlobalConstants;XmlFile)) { var serializer = new DataContractSerializer(typeof(AppSetting)). return (AppSetting)serializer;ReadObject(stream); } }

    The resulting properties will all be encrypted.生成的属性都将被加密。

    Demo fiddle #2 here .演示小提琴#2在这里

Notes:笔记:

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM