我想在创建SQL Server CE数据库时随机生成加密密钥和密码,然后以某种安全的方式保存密钥,以便程序打开连接,但不能轻易通过潜在的攻击者。
我正在开发一个离线WPF应用程序,它将某些用户和设置信息存储在本地数据库中。
我目前的实现是拥有一个用户设置的“设备密码”,用作生成的SQL Server CE数据库密码的加密密钥。然后将base64加密数据库密码保存在简单的.txt设置文件中。当应用程序启动时,用户输入设备密码,该字符串将用作保存密码的解密密钥。如果生成的字符串能够打开与数据库的连接,则密码正确并且程序以完全访问权限打开。
我现在要做的是修改系统以允许具有特定用户名/密码凭据的多个用户打开程序并使用不同级别的权限访问数据库。我试图实现这一点的方法是单独处理用户身份验证,并打开数据库而不管加载一些基本应用程序信息的凭据。
以下是我目前的实施情况:
var candidateDBPwd = DecryptDatabasePassword(passwordBox.Password, Settings.Instance.EncryptedDatabasePassword);
if (candidateDBPwd.IsNullOrEmpty())
{
// User's password didn't decrypt database password.
return false;
}
if (File.Exists(Constants.DB_FILE))
{
// Normal operation: Try to open the database file to see that
// we've got the correct password.
string databaseArguments = Constants.DB_ARGS_SECURE + candidateDBPwd;
using (var conn = new SqlCeConnection(databaseArguments))
{
try
{
conn.Open();
}
catch (System.Data.SqlServerCe.SqlCeException ex)
{
// Failed to open the database: User's password must have been wrong!
return false;
}
}
我花了几个小时来研究类似的问题,现在我开始怀疑它是否可能。共识似乎表明在App.config文件中存储密码或connectionStrings是徒劳的,因为如果加密这些部分,您仍然需要将该密钥存储在代码中的某个位置。关于这个问题的大多数现有的SO线程似乎都已经过时了几年,似乎这种做法已被弃用。是否有一些新的可敬的方式来存储本地数据库密码?或者您会推荐一种不同的方法来实现该功能吗?
答案 0 :(得分:2)
此处的信息是可用于加密app.config
的某些部分的代码段。这是机器特定的加密,我认为这是最简单直接的方式。
我在Click-once应用程序中使用它,以便在首次启动应用程序时加密配置部分。这意味着,它在发布服务器上未加密,它也是未加密的下载,并在安装完成并启动应用程序后立即加密。
因此,使用此方法,您必须以未加密的方式分发文件,并且只有在安装完成后才会对它们进行加密。我想这可以通过在安装期间运行此代码来实现,这取决于您计划如何安装应用程序。
此外,您可以使用UnprotectSection()
解密以前加密的部分。
static void EncryptConfig()
{
// Encrypt config for ClickOnce deploys on first run
// ClickOnce deploys config into 2 dirs, so the parent dir is traversed to encrypt all
if (ApplicationDeployment.IsNetworkDeployed)
{
// Get paths
Assembly asm = Assembly.GetExecutingAssembly();
string exeName = Path.GetFileName(asm.Location);
string configName = exeName + ".config";
DirectoryInfo parentPath = Directory.GetParent(Directory.GetCurrentDirectory());
// Protect config files
foreach (DirectoryInfo dir in parentPath.GetDirectories())
{
foreach (FileInfo fil in dir.GetFiles())
{
if (fil.Name == configName)
{
ExeConfigurationFileMap fileMap = new ExeConfigurationFileMap();
fileMap.ExeConfigFilename = fil.FullName;
Configuration config = ConfigurationManager.OpenMappedExeConfiguration(fileMap, ConfigurationUserLevel.None);
ProtectSection(config, "connectionStrings");
config.Save(ConfigurationSaveMode.Modified);
}
}
}
}
}
private static void ProtectSection(Configuration config, string sectionName)
{
ConfigurationSection section = config.GetSection(sectionName);
if (section != null)
{
if (!section.SectionInformation.IsProtected)
{
section.SectionInformation.ProtectSection("DataProtectionConfigurationProvider");
}
section.SectionInformation.ForceSave = true;
}
else
Tools.LogWarning("Section {1} not found in {0}.",config.FilePath, sectionName);
}
答案 1 :(得分:-1)
您可以将其存储在注册表编辑器中。你提到你的系统是脱机的wpf应用程序。