2017-04-10 4 views
6

私はVisual Studioを使用しており、構成文字列を格納する最良の方法については非常に混乱しています。私はWindowsフォームアプリケーションを作成しています。私は非常に基本的なセキュリティが必要です - 私はapp.configでパスワードを読めるようにしたくありませんが、私はそれを理解するために私のコードを逆アセンブルすることについて心配していません。構成文字列の適切な格納

ので、データソースウィザードでは、私は、「パスワードを保存しないでください」と言った後、私はSettings.Designer.CSに次のコードを置く:

public string MyConnectionString { 
     get { 
      return ((string)("Data Source=SQLSERVER\\ACCOUNTING;Initial Catalog=ACCOUNTING;User ID=MyUser;Password=28947239SKJFKJF")); 
     } 
    } 

私はこれではないことを実現します最良の解決策ですが、私はよりよいものを考えることはできません。私は誰にも助けていただきありがとうと思います。

ありがとう -

ミッシー。 App.configファイルで

+1

最初のWindowsのセキュリティが適切であるかどうかを検討します。 –

+2

[セキュリティで保護された接続文字列](https://msdn.microsoft.com/en-us/library/dx0f3cf2(v=vs.85).aspx) –

+0

このセキュリティシナリオでは、Windowsセキュリティは適切ではありません。 – Missy

答えて

2

標準Rijndaelアルゴリズムを使用して、接続文字列全体を暗号化することができます。アルゴリズムのパスワードとソルト値はコードレベルで保持するだけで済みます(アプリケーション定数と見なすこともできます)。

アプリの設定: -

<?xml version="1.0" encoding="utf-8" ?> 
<configuration> 
    <connectionStrings> 
    <add name="DbContext" connectionString="7ryM3BFhWTwVGpeMWK0pMMujIwj7j+GvrJf7xewEW4Pd+uq0W8aSq85eaEp6+O2Gom98iVNHcyeuaG/93B2y/uJKyHmSnsBlHT3UtBpnT8Lx3OragLK5EXtIiVl38uq10bMga055qq1dACR6XQQeIQ==" providerName="System.Data.SqlClient" /> 
    </connectionStrings> 
</configuration> 

コード: -

class Program 
{ 
    private static string _password = "0B6854E7-20AA-4B0E-978A-410152AA1B41"; 

    static void Main(string[] args) 
    { 
     var connection = System.Configuration.ConfigurationManager.ConnectionStrings["DbContext"].ConnectionString; 
     var salt = "Pa$$w0rd"; 
     var plainConnection = DecryptRijndael(connection, salt); 

     //var encrypted = EncryptRijndael(connection, salt); 

    } 

    public static string EncryptRijndael(string text, string salt) 
    { 
     if (string.IsNullOrEmpty(text)) 
      throw new ArgumentNullException("text"); 

     using(var aesAlg = NewRijndaelManaged(salt)) 
     using(var encryptor = aesAlg.CreateEncryptor(aesAlg.Key, aesAlg.IV)) 
     using (var msEncrypt = new MemoryStream()) 
     { 
      using (var csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write)) 
      using (var swEncrypt = new StreamWriter(csEncrypt)) 
       swEncrypt.Write(text); 

      return Convert.ToBase64String(msEncrypt.ToArray()); 
     } 
    } 

    public static string DecryptRijndael(string cipherText, string salt) 
    { 
     if (string.IsNullOrEmpty(cipherText)) 
      throw new ArgumentNullException("cipherText"); 

     if (!IsBase64String(cipherText)) 
      throw new Exception("The cipherText input parameter is not base64 encoded"); 

     using (var aesAlg = NewRijndaelManaged(salt)) 
     using (var decryptor = aesAlg.CreateDecryptor(aesAlg.Key, aesAlg.IV)) 
     { 
      var cipher = Convert.FromBase64String(cipherText); 

      using (var msDecrypt = new MemoryStream(cipher)) 
      using (var csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read)) 
      using (var srDecrypt = new StreamReader(csDecrypt)) 
       return srDecrypt.ReadToEnd(); 
     } 
    } 

    private static bool IsBase64String(string base64String) 
    { 
     base64String = base64String.Trim(); 
     return (base64String.Length % 4 == 0) && 
       Regex.IsMatch(base64String, @"^[a-zA-Z0-9\+/]*={0,3}$", RegexOptions.None); 
    } 

    private static RijndaelManaged NewRijndaelManaged(string salt) 
    { 
     if (salt == null) throw new ArgumentNullException("salt"); 
     var saltBytes = Encoding.ASCII.GetBytes(salt); 
     using (var key = new Rfc2898DeriveBytes(_password, saltBytes)) 
     { 
      var aesAlg = new RijndaelManaged(); 
      aesAlg.Key = key.GetBytes(aesAlg.KeySize/8); 
      aesAlg.IV = key.GetBytes(aesAlg.BlockSize/8); 

      return aesAlg; 
     } 
    } 
} 

・ホープ、このことができます。

+0

コードにパスワード/暗号キーを埋め込むことは悪いことです。 – Nathan

+0

@Nathan Allは要件に依存します。ユーザーの要件と制限を考慮すると、これは実行可能なソリューションの1つです。 –

+0

悪いアドバイスです。これは、通常、コードプロジェクトからコードをコピーする通常の結果です。コード凍結の数日前にセキュリティ監査に失敗したため、リリースの期限を過ぎて、誰かが遅い夜を過ごすことが予想されます。 (おそらくあなたの答えはソースにあると考えるべきです。)https://www.codeproject.com/Tips/704372/How-to-Use-Rijndael-ManagedEncryption-with-Csharp – Nathan

1

あなたが読めない、接続文字列または特定の文字列を持つようにしたい場合は、registryにそれを置く。..

<appSettings> 
    <add key="dbname" value="dbname"/> 
    <add key="username" value="uname"/> 
    ..... and so on 
</appSettings> 

その後の背後にあるあなたのコードに:

string dbname = ConfigurationManager.AppSettings["dbname"].ToString(); 
は、

ここに完全接続してください:

String yourConnectionString = "DataSorce="DataSourceFromConfig + " " + Password from registry or password from appconfig that encrypted + "" + and so on: 

これはすべてあなたに依存します..

+0

これは良い考えですが、私のセキュリティチームは私にレジストリを使用させません。 – Missy

+0

それは愚かです..誰かがあなたのApp.configにアクセスすると、おそらくあなたのコードの中に何かを保持する可能性があります。 –

9

RsaProtectedConfigurationProviderを使用してConnectionStringsセクションを暗号化できます。ここでは、このセクションの暗号化と復号化するためにどのように短いサンプルが(ただ、管理者として、あなたのVisual Studioを起動し、メモを取る)である:

プライマリWeb構成:

<?xml version="1.0"?> 
<configuration> 
    <startup> 
    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/> 
    </startup> 

    <connectionStrings> 
    <add name="MyConnKey" connectionString="Data Source=SQLSERVER\\ACCOUNTING;Initial Catalog=ACCOUNTING;User ID=MyUser;Password=28947239SKJFKJF" /> 
    </connectionStrings> 

    <appSettings> 
    <add key="DD" value="567_Access"/> 
    </appSettings> 

</configuration> 

コード:

static void Main(string[] args) 
{ 
    Configuration config = ConfigurationManager.OpenExeConfiguration(Application.ExecutablePath); 
    ConfigurationSection section = config.GetSection("connectionStrings") as ConnectionStringsSection; 
    if (!section.SectionInformation.IsProtected) 
    { 
     Console.WriteLine("Protecting connection strings..."); 
     section.SectionInformation.ProtectSection("RsaProtectedConfigurationProvider"); 
    } 
    else 
    { 
     Console.WriteLine("Unprotecting connection strings..."); 
     section.SectionInformation.UnprotectSection(); 
    } 
    section.SectionInformation.ForceSave = true; 
    config.Save(ConfigurationSaveMode.Full); 

    var cs = System.Configuration.ConfigurationManager.ConnectionStrings["MyConnKey"]; 
    Console.WriteLine(cs.ConnectionString); 

    Console.ReadLine(); 
} 

そして、ここに

<?xml version="1.0"?> 
<configuration> 
    <startup> 
    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/> 
    </startup> 

    <connectionStrings configProtectionProvider="RsaProtectedConfigurationProvider"> 
    <EncryptedData Type="http://www.w3.org/2001/04/xmlenc#Element" 
     xmlns="http://www.w3.org/2001/04/xmlenc#"> 
     <EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#tripledes-cbc" /> 
     <KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#"> 
     <EncryptedKey xmlns="http://www.w3.org/2001/04/xmlenc#"> 
      <EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#rsa-1_5" /> 
      <KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#"> 
      <KeyName>Rsa Key</KeyName> 
      </KeyInfo> 
      <CipherData> 
      <CipherValue>js82TLzdIfcdD51g2Us8Nv2eWTSval7oi2Xl+OJsL2c2hUDrm21YG/v1yhuB5Ag8/Uubm9gjmQYcPImo8VOXXDZxEW/HIYNbbkDsopbAyyXNGkHtTrEqz80nqAyipn+Y5QpwXKxFJoaEMPaPdO5juXYd2SPdGaFMBg4m2+drSy6bvXnloz+GIXKbL9QNdxg8br1S8ALUxXsu4F52sKda6J/Sk+I9SBf85XK/JKaHQFoHghf1/m58Zh0hIhci3R6wwGDC3mVG/NcL3tWKpga3ndQ+57FBezsWWOMKyLFPMZG7NkNvBaNG0fYJm2+ApKme1gGil2GGivxySP4evL4hRw==</CipherValue> 
      </CipherData> 
     </EncryptedKey> 
     </KeyInfo> 
     <CipherData> 
     <CipherValue>r28s2mSZTEwb99SIJH7kozBR8RkY8LkxzVLm/VExEwc3aLqSJgqJGrNY6f4mtvCT9ZIYV/QjErt9weQNYSZxyou4RXAq1W8yYnzv+7NCvgOgKvAQh/p+iQidh13SmnC6UCtSrMp3HeRSFNj1y1sF2TGYVpWqWA9NAEBsOyYr0ey6S6/fUFrLAy7mcCkawemmDRvxqF7YnG+LoL9Bh59/l++BhTYlMQvz/stHb5mA6bfKgZYbYDA9KEr5mdrr9t8GGzrk3vNW5s723bKZuiqUWiZfWklY2a2NuONDKj4FG3cAUwCdXq2OzIBFVnXSBgrMo+4GCgQar7delms+bvFOnjozrHdKHJLoahithwPEmDuiM4SJJAZHXKTpFrmv4o+YT68i9xs0iUy0p/hnb5lJv3ITCmEnsOmewn7xIsoPcZMEK54kAtoyjXt2H3QR7KdI3Sf4R6X3rHYr4BerF0UatdP8q5ppLi6uYT/epDi0qTFgf9aDuOW2zDc1TYzFEhBrg4sr2DqqTJWgpyI0yVcq76ZmSTwa53ReyvHFuLkMadijJuUe+u5zPj0BDR6kl8vXN0OzXjby8Uw=</CipherValue> 
     </CipherData> 
    </EncryptedData> 
    </connectionStrings> 

    <appSettings> 
    <add key="DD" value="567_Access"/> 
    </appSettings> 

</configuration> 

コード化された設定は次のようになります。暗号化が最初に処理されたマシンでのみ動作します。詳細はRsaProtectedConfigurationProvider

+0

あなたの長い思いやりのある答えに感謝します。残念ながら、私はすでにこのオプションを評価しており、私にとってはうまくいかないでしょう。 – Missy

+0

@ミッシーこれがうまくいかない理由を詳しく説明できますか?パスワードを保存するための他の多くの安全なオプションはありません。認証にSSPIを使用するのが最善の選択ですが、これは第2位であり、セキュリティスキャンをパスする唯一の方法です。 – Nathan

+0

@Gregor適切な回答をする時間をとっていただきありがとうございます。アドバイスを求めてこのページを閲覧している他の人があなたの答えが最良のアプローチだと理解していることを願っています。 – Nathan

2

別のツールを開発することができます。このツールは接続文字列を入力として受け取り、暗号化された文字列を返します。文字列を暗号化するアルゴリズムを使用する必要があります。

暗号化された接続文字列を取得したら、それを設定ファイルに入れます。 プログラム内のデータベースにアクセスするとき。文字列の暗号化に使用するのと同じsaltパスワードで接続文字列を復号化する必要があります。

1

私が知る限り、これを行うための最良の方法は、@ Gregor Primarの示唆をすることです。

また、この人が提案したものを試すことができます。

https://stackoverflow.com/a/619305/5596684

暗号化を:\フォルダ\ "

復号化:-pdfます。aspnet_regiis "のconnectionStrings" "のconnectionStrings"" C -pefます。aspnet_regiis "c:\ folder \"

接続文字列の設定が表示されることが懸念される場合は、最終行で文字列を暗号化して解読することをお勧めします。ここ

フォローMicrosoftのベストプラクティス:

https://msdn.microsoft.com/en-us/library/89211k9b(v=vs.110).aspx

関連する問題