Azure Key Vault: Gestione sicura di password, chiavi crittografiche e certificati
La gestione sicura delle chiavi di cifratura è un aspetto fondamentale della protezione dei dati nel cloud. Con Azure Key Vault è possibile crittografare chiavi e password e successivamente gestirne la distribuzione, in modo tale che non vengano accidentalmente perse. Utilizzando Azure Key Vault gli sviluppatori non hanno più bisogno di inserire le informazioni relative alla sicurezza all’interno delle proprie applicazioni e nel codice. Ad esempio, se un’applicazione necessita di connettersi ad un database non è necessario mettere le stringhe di connessione nel codice ed è possibile conservarle in maniera sicura in Azure Key Vault.
L’utente o l’applicazione devono prima autenticarsi per poter accedere alle informazioni contenute in Azure Key Vault e successivamente devono essere autorizzate ad effettuare specifiche operazioni. L’autenticazione può essere efffettuata tramite Azure Active Directory, mentre l’autorizzazione può essere effettuata sia tramite role-based access control (RBAC) che con le Azure Key Vault access policy.
In questa guida vedremo:
- Creazione di una Azure Key Vault
- Registrazione di un’applicazione che utilizzerà Azure Key Vault
- Creazione di una access policy per permettere ad un’applicazione di accedere all’Azure Key Vault
- Utilizzo del Key Vault per cifrare i dati di Azure SQL Database
- Creazione e cifratura di una tabella in un Azure SQL Database
- Creazione di una Console Application che funzioni con le Encrypted Columns
Creazione di un Azure Key Vault
Per creare un Azure Key Vault è sufficiente effettuare una ricerca nel portale di Azure ed effettuare la creazione di una nuova risorsa .
Figura 1: Risorsa Key Vault del portale di Azure
Procedete alla creazione della risorsa inserendo la sottoscrizione, il resource group, la region ed il key vault name. Azure Key Vault viene offerto in base a due livelli: Standard e Premium. Alla pagina https://azure.microsoft.com/it-it/pricing/details/key-vault/ trovate maggiori informazioni relative ai prezzi e alle differenze tra i diversi modelli.
Figura 2: Creazione dell’Azure Key Vault
Nella pagina delle Access Policy è possibile definire quali servizi potranno accedere ad Azure Key Vault e quali utenti. Ci occuperemo della modifica di queste informazioni dopo la creazione del vault.
Figura 3: Access Policy di Azure Key Vault
È possibile decidere se la connessione ad Azure Key Vault deve avvenire da qualsiasi indirizzo oppure deve essere consentita soltanto da alcune reti.
Figura 4: Scelta delle reti da cui sarà possibile accedere ad Azure Key Vault
Figura 5: Configurazione di Azure Key Vault completata
La creazione di Azure Key Vault dura pochi secondi. Dal portale di Azure è possibile visualizzare le informazioni principali relative al vault creato.
Figura 6: Overview di Azure Key Vault
Dalla scheda Access Policy, come già detto, è possibile aggiungere delle policy di accesso per consentire ad utenti e applicazioni di accedere al vault.
Figura 7: Gestione delle access policy all’Azure Key Vault
Per modificare i permessi di accesso è sufficiente aprire il menu a tendina relativo alla Key, al Secret o al Certificate e scegliere quello che volete consentire. Consentite, ad esempio, all’utente amministrazione di utilizzare tutti i permessi.
Figura 8: Modifica delle operazioni consentite ad un utente
Per poter aggiungere una nuova access policy al nostro vault è sufficiente cliccare su Add Access Policy e configurare le opzioni di accesso. Nella figura sotto sono mostrati i dettagli di configurazione, i permessi su le chiavi sui segreti e sui certificati che vengono consentiti ad uno specifico utente od una particolare applicazione di Azure AD.
Figura 9: Creazione di una nuova access policy all’Azure Key Vault
Per poter creare una nuova chiave sarà sufficiente cliccare su nodo Keys e dalla scheda che si aprirà scegliere il tipo di chiave che vi interessa, generandola oppure importandola nel vault.
Figura 10: Creazione di una nuova chiave di crittografia in Azure Key Vault
Figura 11: Chiavi di crittografia create in Azure Key Vault
Per creare una nuova password è sufficiente cliccare sul nodo Secrets e digitare il nome e il valore della password. È anche possibile definire una data di scadenza per la password.
Figura 12: Creazione di un nuovo segreto in Azure Key Vault
Figura 13: Segreti disponibili in Azure Key Vault
Come abbiamo visto, la creazione e la configurazione di Azure Key Vault sono veramente semplici. Vediamo ora come testare l’utilizzo di Azure Key Vault.
Registrazione di un’applicazione che utilizzerà Azure Key Vault
Configuriamo un’applicazione che deve accedere a un Azure SQL Database. Quello che faremo sarà configurare l’autenticazione necessaria all’applicazione ad accedere al vault. Per farlo registriamo una nuova applicazione in Azure Active Directory.
Dal portale di Azure andate in Azure Active Directory e nella sezione Manage cliccate su App Registration. Date un nome all’applicazione e inserite un valore nel campo Redirect URI, come mostrato nella figura sotto:
Figura 14: Registrazione di una nuova applicazione in Azure Active Directory
Segnatevi il valore del campo Application (client) ID, perché lo riutilizzeremo in seguito.
Figura 15: Registrazione dell’applicazione completata
Nella sezione Certificates & secrets cliccate su + New client secret ed inserite un nome per la password di accesso dell’applicazione. È anche possibile definire una scadenza per la password
Figura 16: Creazione di una password di accesso per l’applicazione
Segnatevi il valore della chiave, perché lo riutilizzeremo in seguito.
Figura 17: Password di accesso dell’applicazione
Creazione di una access policy per permettere ad un’applicazione di accedere all’Azure Key Vault
Per permettere ad un’applicazione di accedere all’Azure Key Vault è necessario aggiungere una Access Policy. Dal portale di Azure selezionate il vostro Azure Key Vault e dal nodo Access Policy scegliete +Add Access Policy. Scegliete dal menu a tendina il tipo di connettore (nel mio caso SQL Server Connector) e i permessi per l’accesso alla chiave. Concedete i permessi di get,wrapKey,unwrapKey,sign,verify,list
Figura 18: Creazione dei permessi di accesso alle chiavi di Azure Key Vault
Come utente autorizzato scegliete l’app che avete registrato prima. Nel mio caso l’app si chiama SQLApp.
Figura 19: Autorizzazione per la Azure AD registered Application
Come si può vedere dalla figura sotto, adesso ci sono due Access Policy definite.
Figura 20: Access Policy dell’Azure Key Vault
Utilizzo del Key Vault per cifrare i dati di Azure SQL Database
Obiettivo di questo esercizio è creare un nuovo Azure SQL Database ed una tabella che conterrà dei dati crittografati. In questa tabella, dove verranno inseriti dei dati medici, voglio che alcune colonne siano crittografate utilizzando una chiave autogenerata che verrà memorizzata in Azure Key Vault. Successivamente verrà creata un’applicazione che si occuperà di caricare i dati nelle colonne crittografate e successivamente effettuare l’accesso ai dati in maniera sicura utilizzando una stringa di connessione che utilizzerà la chiave contenuta in Azure Key Vault.
Per creare un nuovo Azure SQL Database dal portale di Azure cliccate su + Create a resource> Databases > SQL Database
Figura 21: Creazione di un nuovo Azure SQL Database
Inserite tutte le informazioni richieste per la creazione del database. Nella figura sotto sono riassunti tutti i parametri che ho inserito. Utilizzate la stessa location dove avete creato l’Azure Key Vault.
Figura 22: Parametri per la creazione di un nuovo Azure SQL Database
Figura 23: Configurazioni scelte per la creazione del nuovo SQL Azure Database
Modificate la configurazione del firewall per poter permettere l’accesso all’Azure SQL Database. Cliccate su Set Server firewall e nella nuova scheda cliccate su + Add client IP per aggiungere l’indirizzo IP pubblico da cui state navigando.
Figura 24: Creazione del nuovo Azure SQL Database completata
Figura 25: Aggiunto della regola di firewall per permettere la connessione ad Azure SQL Database
Segnatevi anche i parametri di connessione perché verranno successivamente riutilizzati. Utilizzate il parametro ADO.NET e ricordatevi di sostituire {your_password} con la password scelta al momento della creazione
Figura 26: Parametri di connessione al database
Creazione e cifratura della tabella
Per poter creare e cifrare la tabella appena creata nel nostro Azure SQL Database, collegatevi con SQL Server Management Studio, espandete Databases e cliccando col tasto destro sul database medical scegliete New Query.
Digitate ed eseguite la seguente query SQL per generare la nuova tabella Patients
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
CREATE TABLE [dbo].[Patients]( [PatientId] [int] IDENTITY(1,1), [SSN] [char](11) NOT NULL, [FirstName] [nvarchar](50) NULL, [LastName] [nvarchar](50) NULL, [MiddleName] [nvarchar](50) NULL, [StreetAddress] [nvarchar](50) NULL, [City] [nvarchar](50) NULL, [ZipCode] [char](5) NULL, [State] [char](2) NULL, [BirthDate] [date] NOT NULL PRIMARY KEY CLUSTERED ([PatientId] ASC) ON [PRIMARY] ); |
Figura 27: Creazione della tabella Patients in SQL Server Management Studio
Terminata la creazione della nuova tabella , fate click con il tasto destro su dbo.Patients e scegliete Encrypt Columns
Figura 28: Cifratura delle colonne
Seguite il wizard per la cifratura delle colonne. Modificate la cifratura delle colonne SSN e Birthdate e configurate l’Encryption Type per SSN a Deterministic e per Birthdate a Randomized.
Figura 29: Wizard per la cifratura delle colonne della tabella
In SQL l’opzione Always Encrypted consente di proteggere i dati sensibili crittografandoli a livello di client prima di inserirli nel database. Questo meccanismo supporta due tipi di crittografia: Deterministic e Randomized. Vediamo le differenze principali:
1. Deterministic Encryption (Crittografia Deterministica)
- Come funziona: La crittografia deterministica applica un algoritmo di crittografia che, dato lo stesso valore in input, genera sempre lo stesso valore crittografato in output.
- Caratteristiche: Consente di eseguire confronti di uguaglianza (=) e join su colonne crittografate, perché i valori uguali producono sempre lo stesso output crittografato. Permette l’uso di indici e chiavi esterne (foreign key) sulle colonne crittografate.
- Uso tipico: È utile per dati che devono essere confrontati frequentemente, come numeri di sicurezza sociale o numeri di carta di credito, dove l’uguaglianza è sufficiente.
- Sicurezza: Meno sicura della crittografia randomizzata, perché genera lo stesso valore crittografato per ogni input identico, rendendo potenzialmente possibile dedurre informazioni sui dati in presenza di modelli o frequenze ricorrenti.
2. Randomized Encryption (Crittografia Randomizzata)
- Come funziona: La crittografia randomizzata utilizza un algoritmo che produce un output crittografato diverso per ogni inserimento, anche se il valore in input è lo stesso.
- Caratteristiche: Non consente confronti diretti o join su colonne crittografate. Non permette l’uso di indici o chiavi esterne sulle colonne crittografate.
- Uso tipico: È preferibile per dati estremamente sensibili che non necessitano di confronti frequenti, come note personali, password o dati altamente riservati.
- Sicurezza: Più sicura della crittografia deterministica, poiché non è possibile stabilire una corrispondenza tra due valori identici senza decifrarli.
In sintesi, la crittografia deterministica è utile quando si desidera confrontare o unire dati crittografati, mentre la crittografia randomizzata offre una maggiore sicurezza per dati sensibili che non richiedono confronti diretti.
Figura 30: Scelta delle colonne da crittografare e relativo Encryption Type
Nella pagina Master Key Configuration scegliete Azure Key Vault ed autenticatevi. Selezionate l’Azure Key Vault che volete utilizzare
Figura 31: Scelta dell’Azure Key Vault per la Master Key Configuration
Figura 32: Pagina finale del wizard di crittografia
Figura 33: Pagina di verifica finale
Figura 34: Crittografia delle colonne terminate
Una volta che il processo di crittografia sarà terminato, potrete visualizzare da SQL Server Management Studio che da medical > security > Always Encrypted Key saranno visibili le due chiavi create.
Figura 35: Le chiavi di crittografia sono state create
La Master Key Configuration è visibile nel portale di Azure all’interno delle chiavi dell’Azure Key Vault che avete utilizzato.
Figura 36: La Master Key Configuration è visibile tra le chiavi di Azure Key Vault
Creazione di una Console Application che funzioni con le Encrypted Columns
Per creare una Console Application che funzioni con le Encrypted Columns mi servirò di Visual Studio 2019.
Aprite un nuovo progetto e selezionate Visual C# > Console App (.NET Framework). Date un nome al progetto e scegliete .NET Framework 4.7.2.
Figura 37: Creazione di un nuovo progetto in Visual Studio 2019
Figura 38: Configurazione del nuovo progetto Console App (.NET Framework)
Installate due pacchetti Nuget all’interno del progetto utilizzando Tools > NuGet Package Manager > Package Manager Console
Figura 39: Apertura del Package Manager per l’installazione di due pacchetti Nuget
Nella Package Manager Console lanciate I comandi:
1 2 3 |
Install-Package Microsoft.SqlServer.Management.AlwaysEncrypted.AzureKeyVaultProvider Install-Package Microsoft.IdentityModel.Clients.ActiveDirectory |
Figura 40: Installazione dei package completata
Visualizzate la scheda program.cs e incollate all’interno il seguente codice:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 |
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Data; using System.Data.SqlClient; using Microsoft.IdentityModel.Clients.ActiveDirectory; using Microsoft.SqlServer.Management.AlwaysEncrypted.AzureKeyVaultProvider; namespace AlwaysEncryptedConsoleAKVApp { class Program { // Update this line with your Medical database connection string from the Azure portal. static string connectionString = @"<connection string noted earlier>"; static string clientId = @"<client id noted earlier>"; static string clientSecret = "<key value noted earlier>"; static void Main(string[] args) { InitializeAzureKeyVaultProvider(); Console.WriteLine("Signed in as: " + _clientCredential.ClientId); Console.WriteLine("Original connection string copied from the Azure portal:"); Console.WriteLine(connectionString); // Create a SqlConnectionStringBuilder. SqlConnectionStringBuilder connStringBuilder = new SqlConnectionStringBuilder(connectionString); // Enable Always Encrypted for the connection. // This is the only change specific to Always Encrypted connStringBuilder.ColumnEncryptionSetting = SqlConnectionColumnEncryptionSetting.Enabled; Console.WriteLine(Environment.NewLine + "Updated connection string with Always Encrypted enabled:"); Console.WriteLine(connStringBuilder.ConnectionString); // Update the connection string with a password supplied at runtime. Console.WriteLine(Environment.NewLine + "Enter server password:"); connStringBuilder.Password = Console.ReadLine(); // Assign the updated connection string to our global variable. connectionString = connStringBuilder.ConnectionString; // Delete all records to restart this demo app. ResetPatientsTable(); // Add sample data to the Patients table. Console.Write(Environment.NewLine + "Adding sample patient data to the database..."); InsertPatient(new Patient() { SSN = "999-99-0001", FirstName = "Orlando", LastName = "Gee", BirthDate = DateTime.Parse("01/04/1964") }); InsertPatient(new Patient() { SSN = "999-99-0002", FirstName = "Keith", LastName = "Harris", BirthDate = DateTime.Parse("20/06/1977") }); InsertPatient(new Patient() { SSN = "999-99-0003", FirstName = "Donna", LastName = "Carreras", BirthDate = DateTime.Parse("02/09/1973") }); InsertPatient(new Patient() { SSN = "999-99-0004", FirstName = "Janet", LastName = "Gates", BirthDate = DateTime.Parse("31/08/1985") }); InsertPatient(new Patient() { SSN = "999-99-0005", FirstName = "Lucy", LastName = "Harrington", BirthDate = DateTime.Parse("05/06/1993") }); // Fetch and display all patients. Console.WriteLine(Environment.NewLine + "All the records currently in the Patients table:"); foreach (Patient patient in SelectAllPatients()) { Console.WriteLine(patient.FirstName + " " + patient.LastName + "\tSSN: " + patient.SSN + "\tBirthdate: " + patient.BirthDate); } // Get patients by SSN. Console.WriteLine(Environment.NewLine + "Now lets locate records by searching the encrypted SSN column."); string ssn; // This very simple validation only checks that the user entered 11 characters. // In production be sure to check all user input and use the best validation for your specific application. do { Console.WriteLine("Please enter a valid SSN (ex. 999-99-0003):"); ssn = Console.ReadLine(); } while (ssn.Length != 11); // The example allows duplicate SSN entries so we will return all records // that match the provided value and store the results in selectedPatients. Patient selectedPatient = SelectPatientBySSN(ssn); // Check if any records were returned and display our query results. if (selectedPatient != null) { Console.WriteLine("Patient found with SSN = " + ssn); Console.WriteLine(selectedPatient.FirstName + " " + selectedPatient.LastName + "\tSSN: " + selectedPatient.SSN + "\tBirthdate: " + selectedPatient.BirthDate); } else { Console.WriteLine("No patients found with SSN = " + ssn); } Console.WriteLine("Press Enter to exit..."); Console.ReadLine(); } private static ClientCredential _clientCredential; static void InitializeAzureKeyVaultProvider() { _clientCredential = new ClientCredential(clientId, clientSecret); SqlColumnEncryptionAzureKeyVaultProvider azureKeyVaultProvider = new SqlColumnEncryptionAzureKeyVaultProvider(GetToken); Dictionary<string, SqlColumnEncryptionKeyStoreProvider> providers = new Dictionary<string, SqlColumnEncryptionKeyStoreProvider>(); providers.Add(SqlColumnEncryptionAzureKeyVaultProvider.ProviderName, azureKeyVaultProvider); SqlConnection.RegisterColumnEncryptionKeyStoreProviders(providers); } public async static Task<string> GetToken(string authority, string resource, string scope) { var authContext = new AuthenticationContext(authority); AuthenticationResult result = await authContext.AcquireTokenAsync(resource, _clientCredential); if (result == null) throw new InvalidOperationException("Failed to obtain the access token"); return result.AccessToken; } static int InsertPatient(Patient newPatient) { int returnValue = 0; string sqlCmdText = @"INSERT INTO [dbo].[Patients] ([SSN], [FirstName], [LastName], [BirthDate]) VALUES (@SSN, @FirstName, @LastName, @BirthDate);"; SqlCommand sqlCmd = new SqlCommand(sqlCmdText); SqlParameter paramSSN = new SqlParameter(@"@SSN", newPatient.SSN); paramSSN.DbType = DbType.AnsiStringFixedLength; paramSSN.Direction = ParameterDirection.Input; paramSSN.Size = 11; SqlParameter paramFirstName = new SqlParameter(@"@FirstName", newPatient.FirstName); paramFirstName.DbType = DbType.String; paramFirstName.Direction = ParameterDirection.Input; SqlParameter paramLastName = new SqlParameter(@"@LastName", newPatient.LastName); paramLastName.DbType = DbType.String; paramLastName.Direction = ParameterDirection.Input; SqlParameter paramBirthDate = new SqlParameter(@"@BirthDate", newPatient.BirthDate); paramBirthDate.SqlDbType = SqlDbType.Date; paramBirthDate.Direction = ParameterDirection.Input; sqlCmd.Parameters.Add(paramSSN); sqlCmd.Parameters.Add(paramFirstName); sqlCmd.Parameters.Add(paramLastName); sqlCmd.Parameters.Add(paramBirthDate); using (sqlCmd.Connection = new SqlConnection(connectionString)) { try { sqlCmd.Connection.Open(); sqlCmd.ExecuteNonQuery(); } catch (Exception ex) { returnValue = 1; Console.WriteLine("The following error was encountered: "); Console.WriteLine(ex.Message); Console.WriteLine(Environment.NewLine + "Press Enter key to exit"); Console.ReadLine(); Environment.Exit(0); } } return returnValue; } static List<Patient> SelectAllPatients() { List<Patient> patients = new List<Patient>(); SqlCommand sqlCmd = new SqlCommand( "SELECT [SSN], [FirstName], [LastName], [BirthDate] FROM [dbo].[Patients]", new SqlConnection(connectionString)); using (sqlCmd.Connection = new SqlConnection(connectionString)) { try { sqlCmd.Connection.Open(); SqlDataReader reader = sqlCmd.ExecuteReader(); if (reader.HasRows) { while (reader.Read()) { patients.Add(new Patient() { SSN = reader[0].ToString(), FirstName = reader[1].ToString(), LastName = reader["LastName"].ToString(), BirthDate = (DateTime)reader["BirthDate"] }); } } } catch (Exception ex) { throw; } } return patients; } static Patient SelectPatientBySSN(string ssn) { Patient patient = new Patient(); SqlCommand sqlCmd = new SqlCommand( "SELECT [SSN], [FirstName], [LastName], [BirthDate] FROM [dbo].[Patients] WHERE [SSN]=@SSN", new SqlConnection(connectionString)); SqlParameter paramSSN = new SqlParameter(@"@SSN", ssn); paramSSN.DbType = DbType.AnsiStringFixedLength; paramSSN.Direction = ParameterDirection.Input; paramSSN.Size = 11; sqlCmd.Parameters.Add(paramSSN); using (sqlCmd.Connection = new SqlConnection(connectionString)) { try { sqlCmd.Connection.Open(); SqlDataReader reader = sqlCmd.ExecuteReader(); if (reader.HasRows) { while (reader.Read()) { patient = new Patient() { SSN = reader[0].ToString(), FirstName = reader[1].ToString(), LastName = reader["LastName"].ToString(), BirthDate = (DateTime)reader["BirthDate"] }; } } else { patient = null; } } catch (Exception ex) { throw; } } return patient; } // This method simply deletes all records in the Patients table to reset our demo. static int ResetPatientsTable() { int returnValue = 0; SqlCommand sqlCmd = new SqlCommand("DELETE FROM Patients"); using (sqlCmd.Connection = new SqlConnection(connectionString)) { try { sqlCmd.Connection.Open(); sqlCmd.ExecuteNonQuery(); } catch (Exception ex) { returnValue = 1; } } return returnValue; } } class Patient { public string SSN { get; set; } public string FirstName { get; set; } public string LastName { get; set; } public DateTime BirthDate { get; set; } } |
Sostituite I valori Connection string, clientId e clientSecret con quelli che vi avevo detto di memorizzare precedentemente. Connection String è la stringa ADO.NET per la connessione all’Azure SQL database, mentre clientId e clientSecret sono i valori della App che avete registrato in Azure AD.
Figura 41: Applicazione che utilizzerà la Encrypted Columns
A questo punto lanciate il programma cliccando su Start. La Console Application effettuerà prima il Build e successivamente verrà eseguita. Come prima operazione aggiungerà dei dati all’applicazione e dopo vi verrà chiesta qual è la password per potervi connettere al server. Inserite quindi la password richiesta.
Figura 42: Esecuzione dell’appllicazione e connessione al server
Lasciate l’applicazione in Running e spostatevi in SQL Management Studio. Cliccate col tasto destro sul database medical e selezionate New Query.
Eseguite la query
1 |
SELECT FirstName, LastName, SSN, BirthDate FROM Patients; |
per visualizzare che i dati che sono stati inseriti nelle colonne crittografate. Noterete che i dati non sono in chiaro ma sono visualizzati in maniera crittografata.
Figura 43: I dati inseriti dall’applicazione sono crittografati
Ritornate nell’applicazione e nel prompt Enter a Valid SSN inserite il valore 999-99-0003. Verrà effettuata una query che riporterà i dati da una colonna crittografata. Poiché l’applicazione ha accesso alla chiave contenuta nell’Azure Key Vault, i dati sono visualizzati in chiaro.
Figura 44: L’applicazione è in grado di visualizzare i dati in chiaro perché ha accesso alla chiave contenuta nell’Azure Key Vault
Conclusioni
Abbiamo bisogno di proteggere le nostre password, i nostri certificati e le nostre chiavi di crittografia. Azure Key Vault permette di poterle gestire in maniera sicura e permette di aumentare considerevolmente la sicurezza dei dati e delle applicazioni.
Per maggiori informazioni vi rimando alla lettura della documentazione ufficiale https://docs.microsoft.com/en-us/azure/key-vault/