我有一个项目(Windows Forms Application),它使用LinqToSql连接到数据库。它的连接字符串(包括密码)存储在app.config文件中。
这个程序被我工作的一群人使用,所以我考虑了安全性并决定加密连接字符串。
我已经阅读了一些有关此问题的文章,并发现有一种内置方法可以保护配置文件中的某些部分。我甚至找到了使用此工具的几个例子(例如:Encrypt Connection Strings when using Linq To SQL)。
但我还有疑问: 1.在程序中,我必须称这些方法?
在我的解决方案的数据层中,有很多这样的地方:
using(var db = new myDbDataContext())
{
//some code
}
这是否意味着我每次尝试从数据库中获取内容时都必须调用这些加密/解密方法?或者此代码必须包含在program.cs文件中?或者在dbml文件中?
如果使用此加密工具,还要将app.config重命名为web.config。我几次见过这个推荐。这是真的,我需要这样做吗?
加密如何在不同的工作站上运行?是否需要对代码进行任何其他更改?
答案 0 :(得分:1)
请看看它会对你有所帮助。
public class TestContext : DbContext
{
// this is wt we use in application we can delete default ctor it is not required
public TestContext(string connectionName)
{
// i m reading a already encrypted connection string from config
// decrpt it and set the connction of db context
var conn = ConfigurationManager.ConnectionStrings["EncryptedConnection"].ConnectionString;
this.Database.Connection.ConnectionString = Encrypt.DecryptString(conn, "myKey");
}
public virtual DbSet<Contact> Contacts { get; set; }
}
config
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<configSections>
<!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 -->
<section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
</configSections>
<connectionStrings>
<add name="EncryptedConnection" connectionString="qIhXH2MDWohYjOPJ3BiA7A4E70kRjRW3aSOMixpASFHu1oyak2YEMO3BTaRr3s5eVtuvi5dY07vK+PUm1xFZ6D1XT/qJjDvrs1SpbTHe45g=" providerName="System.Data.SqlClient" />
</connectionStrings>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
</startup>
<entityFramework>
<defaultConnectionFactory type="System.Data.Entity.Infrastructure.LocalDbConnectionFactory, EntityFramework">
<parameters>
<parameter value="mssqllocaldb" />
</parameters>
</defaultConnectionFactory>
<providers>
<provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
</providers>
</entityFramework>
</configuration>
---在appplication中使用
static void Main(string[] args)
{
// here I am using first takes a valid connectionstring from encrypt it.
// this is needed because I am showing it in console application idealy this step is independent of this
// this needs to be done by some build and deployment tool which wil copy this encrypted string to app.config
var encryptString = Encrypt.EncryptString("Data Source=yashssd;Initial Catalog=StackOverFlow1;Integrated Security=True", "myKey");
// this encryped connecton string I will save to th app.config manauly but this can be auutomated with build/ deployment tools
//var decrypt = Encrypt.DecryptString(encryptString, "myKey");
using (var ctx = new TestContext("EncryptedConnection"))
{
// for testing to see al working
//this is important to read the entity first .
var contact = ctx.Contacts.FirstOrDefault(x => x.ContactID == 1);
}
Console.ReadLine();
}
最终 - 加密/解密的逻辑 //这可以是一个单独的应用程序,它的功能是为不同的应用程序提供加密密钥我只是拿了一个我可以在互联网上找到它,或者可以根据用户需要更安全。
public static class Encrypt
{
// This size of the IV (in bytes) must = (keysize / 8). Default keysize is 256, so the IV must be
// 32 bytes long. Using a 16 character string here gives us 32 bytes when converted to a byte array.
private const string initVector = "pemgail9uzpgzl88";
// This constant is used to determine the keysize of the encryption algorithm
private const int keysize = 256;
//Encrypt
public static string EncryptString(string plainText, string passPhrase)
{
byte[] initVectorBytes = Encoding.UTF8.GetBytes(initVector);
byte[] plainTextBytes = Encoding.UTF8.GetBytes(plainText);
PasswordDeriveBytes password = new PasswordDeriveBytes(passPhrase, null);
byte[] keyBytes = password.GetBytes(keysize / 8);
RijndaelManaged symmetricKey = new RijndaelManaged();
symmetricKey.Mode = CipherMode.CBC;
ICryptoTransform encryptor = symmetricKey.CreateEncryptor(keyBytes, initVectorBytes);
MemoryStream memoryStream = new MemoryStream();
CryptoStream cryptoStream = new CryptoStream(memoryStream, encryptor, CryptoStreamMode.Write);
cryptoStream.Write(plainTextBytes, 0, plainTextBytes.Length);
cryptoStream.FlushFinalBlock();
byte[] cipherTextBytes = memoryStream.ToArray();
memoryStream.Close();
cryptoStream.Close();
return Convert.ToBase64String(cipherTextBytes);
}
//Decrypt
public static string DecryptString(string cipherText, string passPhrase)
{
byte[] initVectorBytes = Encoding.ASCII.GetBytes(initVector);
byte[] cipherTextBytes = Convert.FromBase64String(cipherText);
PasswordDeriveBytes password = new PasswordDeriveBytes(passPhrase, null);
byte[] keyBytes = password.GetBytes(keysize / 8);
RijndaelManaged symmetricKey = new RijndaelManaged();
symmetricKey.Mode = CipherMode.CBC;
ICryptoTransform decryptor = symmetricKey.CreateDecryptor(keyBytes, initVectorBytes);
MemoryStream memoryStream = new MemoryStream(cipherTextBytes);
CryptoStream cryptoStream = new CryptoStream(memoryStream, decryptor, CryptoStreamMode.Read);
byte[] plainTextBytes = new byte[cipherTextBytes.Length];
int decryptedByteCount = cryptoStream.Read(plainTextBytes, 0, plainTextBytes.Length);
memoryStream.Close();
cryptoStream.Close();
return Encoding.UTF8.GetString(plainTextBytes, 0, decryptedByteCount);
}
}