2012-05-15 18 views
6

Ho bisogno di sapere qual è il modo comune di memorizzare una stringa di connessione server SQL per un'applicazione WinForms in VB.NET.Come archiviare in modo sicuro una stringa di connessione in un'applicazione WinForms?

ho cercato la rete e ho trovato le risposte a ciascuna delle seguenti domande:

  • Come faccio a leggere i valori app.config
  • Come fare in ASP.NET Riferimento: this SO question.
  • Come faccio a memorizzare una stringa di connessione (in chiaro in tal modo non sicuro)

Vorrei una risposta completa su come memorizzare una stringa di connessione in VB.NET in app.config (o settings.settings se è meglio) in modo sicuro.

È il app.config il posto giusto? Posso crittografare questi valori?

risposta

9

Semplicemente, il framework .NET permette di fare questo, vedi

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

Informazioni rilevanti:

Questo va nella machine.config di file:

<configProtectedData defaultProvider="RsaProtectedConfigurationProvider"> 
    <providers> 
    <add name="RsaProtectedConfigurationProvider" 
     type="System.Configuration.RsaProtectedConfigurationProvider, ... /> 
    <add name="DataProtectionConfigurationProvider" 
     type="System.Configuration.DpapiProtectedConfigurationProvider, ... /> 
    </providers> 
</configProtectedData> 

E questo è il codice dell'applicazione:

Shared Sub ToggleConfigEncryption(ByVal exeConfigName As String) 
    ' Takes the executable file name without the 
    ' .config extension. 
    Try 
     ' Open the configuration file and retrieve 
     ' the connectionStrings section. 
     Dim config As Configuration = ConfigurationManager. _ 
      OpenExeConfiguration(exeConfigName) 

     Dim section As ConnectionStringsSection = DirectCast(_ 
      config.GetSection("connectionStrings"), _ 
      ConnectionStringsSection) 

     If section.SectionInformation.IsProtected Then 
      ' Remove encryption. 
      section.SectionInformation.UnprotectSection() 
     Else 
      ' Encrypt the section. 
      section.SectionInformation.ProtectSection(_ 
       "DataProtectionConfigurationProvider") 'this is an entry in machine.config 
     End If 

     ' Save the current configuration. 
     config.Save() 

     Console.WriteLine("Protected={0}", _ 
     section.SectionInformation.IsProtected) 

    Catch ex As Exception 
     Console.WriteLine(ex.Message) 
    End Try 
End Sub 

UPDATE 1

Grazie @wpcoder, per this link

+0

Dovrei pensare che lo farò, grazie. – MarioDS

+1

Poiché questa domanda sta ottenendo un sacco di punti di vista, ho modificato la tua risposta per assicurarmi che le informazioni non vadano perse in caso di interruzione del collegamento. – MarioDS

+1

@pylover _Questo risponde alla domanda ma non fornisce una soluzione adeguata_. Dal link MS fornito; la nota ** dice **: 'La stringa di connessione può essere decifrata solo sul computer su cui è stata crittografata. Il [collegamento MS aggiornato per l'articolo potrebbe fornire la soluzione] (https://docs.microsoft.com/en-us/dotnet/framework/data/adonet/protecting-connection-information) – wpcoder

5

Al mio lavoro, archiviamo le stringhe di connessione complete nell'app.config, ma le crittografiamo con AES256. Funziona abbastanza bene e aggiunge una buona dose di sicurezza. Abbiamo scritto un piccolo strumento che consente di crittografare e decrittografare le stringhe di connessione, quindi modificare i file app.config è piuttosto semplice. Abbiamo solo la chiave di crittografia codificata nell'applicazione, quindi se qualcuno si preoccupa di decompilare gli assembly, potrebbe capirlo, ma alza la barra abbastanza in alto per le nostre esigenze. Ecco la classe che usiamo per crittografare e decrittografare le stringhe di connessione:

Public Class Aes256Base64Encrypter 
    Public Function Decrypt(ByVal encryptedText As String, ByVal secretKey As String) As String 
     Dim plainText As String = Nothing 
     Using inputStream As MemoryStream = New MemoryStream(System.Convert.FromBase64String(encryptedText)) 
      Dim algorithm As RijndaelManaged = getAlgorithm(secretKey) 
      Using cryptoStream As CryptoStream = New CryptoStream(inputStream, algorithm.CreateDecryptor(), CryptoStreamMode.Read) 
       Dim outputBuffer(0 To CType(inputStream.Length - 1, Integer)) As Byte 
       Dim readBytes As Integer = cryptoStream.Read(outputBuffer, 0, CType(inputStream.Length, Integer)) 
       plainText = Unicode.GetString(outputBuffer, 0, readBytes) 
      End Using 
     End Using 
     Return plainText 
    End Function 


    Public Function Encrypt(ByVal plainText As String, ByVal secretKey As String) As String 
     Dim encryptedPassword As String = Nothing 
     Using outputStream As MemoryStream = New MemoryStream() 
      Dim algorithm As RijndaelManaged = getAlgorithm(secretKey) 
      Using cryptoStream As CryptoStream = New CryptoStream(outputStream, algorithm.CreateEncryptor(), CryptoStreamMode.Write) 
       Dim inputBuffer() As Byte = Unicode.GetBytes(plainText) 
       cryptoStream.Write(inputBuffer, 0, inputBuffer.Length) 
       cryptoStream.FlushFinalBlock() 
       encryptedPassword = System.Convert.ToBase64String(outputStream.ToArray()) 
      End Using 
     End Using 
     Return encryptedPassword 
    End Function 


    Private Function getAlgorithm(ByVal secretKey As String) As RijndaelManaged 
     Const salt As String = "put a salt key here" 
     Const keySize As Integer = 256 

     Dim keyBuilder As Rfc2898DeriveBytes = New Rfc2898DeriveBytes(secretKey, Unicode.GetBytes(salt)) 
     Dim algorithm As RijndaelManaged = New RijndaelManaged() 
     algorithm.KeySize = keySize 
     algorithm.IV = keyBuilder.GetBytes(CType(algorithm.BlockSize/8, Integer)) 
     algorithm.Key = keyBuilder.GetBytes(CType(algorithm.KeySize/8, Integer)) 
     algorithm.Padding = PaddingMode.PKCS7 
     Return algorithm 
    End Function 
End Class 

In realtà, abbiamo avvolto che all'interno di una classe, che ConnectionStringEncrpyter hardcodes la chiave segreta.

+0

Che suona bene, ma mi puoi dire come codificare esso? Ho una classe di crittografia pronta solo per le password, non per le intere stringhe di connessione (overhead-wise) – MarioDS

+0

@MarioDeSchaepmeester Ho aggiunto qualche codice di esempio. Capisco - la crittografia può essere un dolore. Lo codifichiamo in base64, quindi si memorizza bene nel file di testo. –

+0

Grazie per l'aiuto, ma penso che Pylover mi abbia fornito la risposta che stavo cercando. – MarioDS

Problemi correlati