我是这样做的:
提供者实施:
public class X509ProtectedConfigProvider : ProtectedConfigurationProvider
{
#region Fields
private X509Certificate2 cert;
#endregion
// Performs provider initialization.
#region Public Methods and Operators
public override XmlNode Decrypt(XmlNode encryptedNode)
{
// Load config section to encrypt into xmlDocument instance
XmlDocument doc = encryptedNode.OwnerDocument;
EncryptedXml eXml = new EncryptedXml(doc);
eXml.DecryptDocument();
return doc.DocumentElement;
}
public override XmlNode Encrypt(XmlNode node)
{
// Load config section to encrypt into xmlDocument instance
XmlDocument doc = new XmlDocument { PreserveWhitespace = true };
doc.LoadXml(node.OuterXml);
// Encrypt it
EncryptedXml eXml = new EncryptedXml();
EncryptedData eData = eXml.Encrypt(doc.DocumentElement, this.cert);
return eData.GetXml();
}
public override void Initialize(string name, NameValueCollection config)
{
base.Initialize(name, config);
string certSubjectDistName = config["CertSubjectDistinguishedName"];
string certStoreName = config["CertStoreName"];
X509Store certStore = !string.IsNullOrEmpty(certStoreName) ? new X509Store(certStoreName, StoreLocation.LocalMachine) : new X509Store(StoreLocation.LocalMachine);
try
{
certStore.Open(OpenFlags.ReadOnly);
X509Certificate2Collection certs = certStore.Certificates.Find(
X509FindType.FindBySubjectName, certSubjectDistName, true);
this.cert = certs.Count > 0 ? certs[0] : null;
}
finally
{
certStore.Close();
}
}
#endregion
}
助手类:
public static class Crypto
{
// Protect the connectionStrings section.
#region Public Methods and Operators
public static bool ProtectConfiguration(string path)
{
string provider = "X509ProtectedConfigProvider";
// Get the application configuration file.
Configuration config = ConfigurationManager.OpenExeConfiguration(path);
// Get the section to protect.
ConfigurationSection connStrings = config.ConnectionStrings;
if (connStrings != null)
{
if (!connStrings.SectionInformation.IsProtected)
{
if (!connStrings.ElementInformation.IsLocked)
{
// Protect the section.
connStrings.SectionInformation.ProtectSection(provider);
connStrings.SectionInformation.ForceSave = true;
config.Save(ConfigurationSaveMode.Full);
return true;
}
return false;
}
return true;
}
return false;
}
// Unprotect the connectionStrings section.
public static void UnProtectConfiguration(string path)
{
// Get the application configuration file.
Configuration config = ConfigurationManager.OpenExeConfiguration(path);
// Get the section to unprotect.
ConfigurationSection connStrings = config.ConnectionStrings;
if (connStrings != null)
{
if (connStrings.SectionInformation.IsProtected)
{
if (!connStrings.ElementInformation.IsLocked)
{
// Unprotect the section.
connStrings.SectionInformation.UnprotectSection();
connStrings.SectionInformation.ForceSave = true;
config.Save(ConfigurationSaveMode.Full);
}
}
}
}
#endregion
}
}
App.Config(注意 configProtectedData):
<?xml version="1.0"?>
<configuration>
<configSections>
<section name="nlog" type="NLog.Config.ConfigSectionHandler, NLog"/>
</configSections>
<connectionStrings>
<add name="MyDbConnStr" providerName="System.Data.SqlClient" connectionString="Data Source=localhost;Initial Catalog=MyDb;Integrated Security=True;"/>
</connectionStrings>
<appSettings>
<add key="SiteName" value="MyAwesomeSite"/>
</appSettings>
<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/></startup>
<configProtectedData>
<providers>
<add CertSubjectDistinguishedName="localhost" CertStoreName="MyCertKeyStore" name="X509ProtectedConfigProvider" type="ProtectedConfigProvider.X509ProtectedConfigProvider, X509ProtectedConfigProvider, Version=1.0.0.0, Culture=neutral, PublicKeyToken=098027505e2ed139" />
</providers>
</configProtectedData>
</configuration>
程序(使用):
...
ProtectConfiguration("mysuperawesomeapp.exe);
DatabaseFactory.SetDatabaseProviderFactory(new DatabaseProviderFactory());
Database db = DatabaseFactory.CreateDatabase("MyDbConnStr");
从 db 读取数据适用于加密的应用程序配置“connectionStrings”部分。:)