我正在尝试将一些连接字符串作为加密的文本保存到我的类中的xml中。
这是我的课程:
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);
}
}
}
这就是我保存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);
}
}
}
}
我的保存工作正常,但是没有将值保存为加密的字符串。
我以为这可以即时处理,但它什么也没做:
public string DataSource
{
set => _dataSource = Encryption.SimpleEncryptWithPassword(value, GlobalConstants.EncryptionPassword);
get => Encryption.SimpleDecryptWithPassword(_dataSource, GlobalConstants.EncryptionPassword);
}
我没有收到任何错误消息,只是没有加密数据。
关于在保存某些属性之前如何加密某些属性的任何建议?
编辑:如果可以阻止,我宁愿不加密整个文件。我只想加密我选择的属性。 ty!
您的问题是XmlSerializer
仅序列化public属性和字段-并且AppSetting
类中的公共属性都未加密。从docs
XML序列化仅将对象的公共字段和属性值序列化为XML流。 ...
XML序列化不会转换方法,索引器,私有字段或只读属性(只读集合除外)。要序列化所有对象的公共和私有字段和属性,请使用DataContractSerializer而不是XML序列化。
因此您的选择是:
为加密成员提供公共属性,并用XmlIgnore
标记纯文本属性,如下所示:
XmlIgnore
演示小提琴#1 [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);
}
。
切换至here。首先修改您的类,如下所示:
DataContractSerializer
然后如下修改DataContractSerializer
:
[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
结果属性将全部加密。
演示小提琴#2 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);
}
}
中,请勿处置here。这将使文件保持打开状态,并可能在以后导致错误。相反,请执行:
WriteAppSettingsToXmlFile()
虽然以StreamWriter
序列化的属性必须是公开的,但您可以通过用public static void WriteAppSettingsToXmlFile(AppSetting appSetting)
{
var xs = new XmlSerializer(typeof(AppSetting));
using (var tw = new StreamWriter(GlobalConstants.XmlFile))
{
xs.Serialize(tw, appSetting);
}
}
,XmlSerializer
和[Browsable(false)]
标记它们来稍微隐藏它们。