Summary This article provides information on the security fundamentals and best practices when working with Windows Azure SQL Database. This article is primarily concerned with writing secure connection strings for SQL Database.
Author: Selcin Turkarslan Reviewers: Evan Basalik, Larry Franks, Marius Omusoru, Shawn Hernan Table of Contents Introduction SQL Database Firewall Authentication and Logins and Users SQL Server Data Encryption General Best Practices on Writing Secure Applications for SQL Database Best Practices on Writing Secure Connection Strings for SQL Database Example Connection Strings ADO.NET ODBC PHP Create and deploy an ASP.NET application with Security in mind Download and Compile the Protected Configuration Provider Create ASP.NET SQL Database Project Create and Import a Certificate Overview of Certificates in Windows Azure Create a Self-signed Certificate Import the Public Key to Your Local Certificate Store Update ASP.NET Project with Security in Mind Deploy ASP.NET Project to Windows Azure Create a Service Package Create a Hosted Service Upload a Certificate to the Windows Certificate Store Using the Management Portal Deploy the Application to the Staging Environment Test the application in the Staging Environment Promote the Application to Production Conclusion Additional Resources
To help protect your data, Windows Azure and SQL Database provides a set of mechanisms that you can follow or implement in your application.
The following section lists the fundamental security mechanisms that you need to know while developing SQL Database applications.
The SQL Database service is only available through TCP port 1433. To access a SQL Database from your computer, you must ensure that your firewall allows outgoing TCP communication on TCP port 1433.
The SQL Database firewall grants access based on the originating IP address of each request. Before you can connect to the SQL Database server for the first time, you must use the Windows Azure Platform Management Portal to specify which IP addresses are allowed through the firewall. You will need to create one or more firewall rules that enable connection attempts from the IP addresses used by client computers as well as Windows Azure. For more information, see Windows Azure SQL Database Firewall.
Important: Use the SQL Database firewall to allow the network traffic from only the trusted IP addresses.
SQL Database supports only SQL Server Authentication. Windows Authentication (integrated security) is not supported. Users must provide credentials (login and password) every time they connect to SQL Database.
Security administration in SQL Database is similar to security administration for an on-premise instance of SQL Server. For more information, see Managing Databases and Logins in Windows Azure SQL Database.
Important: Create minimal privilege accounts to be used in the connection strings. Do not use the administrator account in the connection string.
SQL Database does not support the data encryption mechanisms supported in SQL Server. For example, transparent data encryption, asymmetric keys, symmetric keys, and Transact-SQL functions such as ENCRYPTBYPASSPHRASE, and DECRYPTBYPASSPHRASE; CREATE/ALTER/DROP DATABASE ENCRYPTION KEY or CREATE/ALTER/DROP MASTER KEY are not supported in SQL Database.
With SQL Database, you need to encrypt or decrypt at the application level. In other words, your application is responsible for encryption/decryption of the sensitive data when uploading/retrieving to/from SQL Database.
To improve your application’s security, follow these guidelines:
For more information on how to use Pkcs12 Protected Configuration Provider, see Download and Install Protected Configuration Provider below.
In summary:
Important: In this section, we focused on the cryptography and securing user accounts. Keep in mind that any kind of application might face attacks coming from code flaws and vulnerabilities such as cross-site scripting, SQL injection, cross-site request forgery, connection string injection, and memory corruption. To learn more about how to protect your application from such attacks and others, visit Microsoft Security Development Lifecycle and Security Resources for Windows Azure.
All communications between SQL Database and your application are encrypted using Secure Sockets Layer (SSL) at all times. SQL Database doesn’t support unencrypted connections. SQL Database has a signed-certificate that is issued by a Certificate Authority (CA).
When accessing your SQL Database, if your client application does not validate certificates upon connection, your connection to SQL Database is susceptible to "man in the middle" attacks.
To validate certificates with application code or tools, explicitly request an encrypted connection and do not trust the server certificates. If your application code or tools do not request an encrypted connection, they will still receive encrypted connections. However, they may not validate the server certificates and thus will be susceptible to "man in the middle" attacks.
Important: We recommend that you do not explicitly turn off the SSL encryption in the connection string.
This section provides example connection strings for ADO.NET, ODBC, and PHP drivers. You can also find the example connection strings on the Windows Azure Management Portal. For more information on the connection properties of each driver, see:
Note: We recommend that you use the connection string builders if your application constructs the connection strings at run time.
To validate certificates with ADO.NET application code, set Encrypt=True and TrustServerCertificate=False in the database connection string.
Server=tcp:servername.database.windows.net,1433;Database=TestDB;UserID=username@servername; Password=myPassword;Trusted_Connection=False;Encrypt=True;
Driver={SQL Server Native Client 10.0};Server=tcp:servername.database.windows.net,1433;Database=TestDB;Uid=username@iwp8mjbs6b;Pwd=myPassword;Encrypt=yes;
To validate certificates with PHP application code, set Encrypt=True and TrustServerCertificate=False in the database connection string. The following connection string asks the PHP driver to validate the server certificate. Since SQL Database has a valid signed-certificate, the server certificate validation succeeds and a connection is established.
$connectionInfo = array("Database"=>$dbName, "UID"=>$userName, "PWD"=>$userPassword,
"MultipleActiveResultSets"=>true, "Encrypt"=>true, "TrustServerCertificate"=>false);
$serverName = "tcp:servername.database.windows.net,1433";
$conn = sqlsrv_connect($serverName, $connectionInfo);
While developing SQL Database applications, you must ensure that your connection string is secure. If your connection string is written in plain text format, and includes user name and password to your production database, it is not secure. You need to ensure that your connection string is secure but at the same time you must allow the code running on Windows Azure to be able to read your connection string. We recommend that you must encrypt sensitive data in your configuration files, such as web.config.
We also recommend that you must store encryption keys in a secure location, and do not hard-code into the application code. Windows Azure provides a secure certificate store where you can maintain your certificates. You deploy an X.509 certificate with a key pair to Windows Azure and it can be used for encryption/decryption.
This article uses the existing ASP.NET code example that is provided in the SQL Database documentation and demonstrates how to make its database connection string more secure in the Windows Azure platform.
Before you deploy any application to Windows Azure, you must have already created a Windows Azure subscription through the Management Portal. For more information, see How to Setup a Windows Azure Subscription.
The following tasks demonstrate how to make the configuration settings of the ASP.NET code example secure and how to deploy and run it as a service on Windows Azure.
You must encrypt the configuration settings (such as SQL Database connection strings) stored in configuration files (such as the web.config) as they contain sensitive information. To help secure information in configuration files, ASP.NET provides a feature called protected configuration, which enables you to encrypt sensitive information in a configuration file. The recommended approach is to use either of the protected configuration providers included in the .NET Framework DpapiProtectedConfigurationProvider or the RsaProtectedConfigurationProvider .
But neither the DpapiProtectedConfigurationProvider nor the RsaProtectedConfigurationProvider included in .NET Framework works on Windows Azure. Instead, use a custom protected configuration provider Pkcs12 Protected Configuration Provider to encrypt configuration settings in a web.config file deployed on Windows Azure.
1. Download Pkcs12 Protected Configuration Provider .zip with source code from the MSDN Code Gallery.
2. Save PKCS12ProtectedConfigurationProvider.zip file to your local machine.
3. Open the PKCS12ProtectedConfigurationProvider.sln file with Visual Studio.
4. Click Build | Build Solution and Build Installer in the Tool menu.
5. There should be a setup.exe file in the Installer\release directory.
6. Execute this setup.exe to install the provider.
The installer will put Pkcs12CertProtectedConfiguratoinProvider.dll assembly file into the Global Assembly Cache so that the aspnet_regiis.exe can find it when you want to encrypt the web.config.
To make sure that it is installed to GAC, run this in the command prompt:
C:\>gacutil -l PKCS12ProtectedConfigurationProvider
Microsoft (R) .NET Global Assembly Cache Utility. Version 4.0.30319.1
Copyright (c) Microsoft Corporation. All rights reserved.
The Global Assembly Cache contains the following assemblies:
PKCS12ProtectedConfigurationProvider, Version=1.0.0.0, Culture=neutral, Public
KeyToken=34da007ac91f901d, processorArchitecture=MSIL
Number of items = 1
For more information about the gacutil tool, see Gacutil.exe.
Follow the steps provided in How to: Connect to Windows Azure SQL Database Through ASP.NET topic to create your test database in SQL Database and your Visual Studio project. The article assumes that the reader is familiar with the ASP.NET code example and he/she already can compile it in a local computer.
To ensure that only Windows Azure can read your database connection string in the Windows Azure package, you must encrypt your database connection string and let Windows Azure know how to decrypt it. To do that you must pre-deploy a certificate to the Windows Azure Certificate Store.
This section first provides an overview of Windows Azure certificates. Then, the section describes how to create a certificate and import it your local certificate store.
Depending on the type of application that you develop for Windows Azure, you may need different types of certificates, such as:
This article demonstrates how to create a service certificate specifically. The following image shows the process of adding a new certificate to a subscription's certificate store. We recommend that you use a signed-certificate that is issued by a Certificate Authority (CA) for production applications. For more information on how to get certificates for a production application, see How to Obtain an SSL Certificate. If you don't have a certificate that has been issued by a certificate authority, you can generate a self-signed certificate for use with your Windows Azure service. This article uses a self-signed certificate as an example.
1. Open a Visual Studio command prompt (run as administrator), you will find the command prompt in the start menu under Visual Studio tools.
2. Execute this command:
makecert -r -pe -n "CN=xxxazurehost1" -sky exchange "xxxazurehost1.cer" -sv "xxxazurehost1.pvk"
For more information on how to use the makecert utility, see How to: Create Temporary Certificates for Use During Development and How to Create a Certificate for a Role.
3. Enter your password (e.g. yourpassword) for three times. 4. This will generate an xxxazurehost1.cer (the public key certificate) and an xxxazurehost1.pvk (the private key file) file.
5. Then enter the following command to create the .pfx file (this format is used to import the private key to Windows Azure). After the –pi switch, enter the password you chose.
pvk2pfx -pvk "xxxazurehost1.pvk" -spc "xxxazurehost1.cer" -pfx "xxxazurehost1.pfx" -pi yourpassword
6. You can verify that the certificate has been created in the current directory in the Visual Studio command prompt.
1. Click Start, type mmc in the Search programs and files box, and then press ENTER.
2. On the File menu, click Add/Remove Snap-in.
3. Under Available snap-ins, double-click Certificates.
4. Select Computer account, and then click Next.
5. Click Local computer, and then click Finish. Click OK.
6. Under Console Root, Certificates (Local Computer), in the Personal store, click Certificates. Right click, under All Tasks, click Import. This opens the Certificate Import Wizard. (This wizard helps you copy certificates from your disk to a certificate store.) Click Next. Browse to the .pfx file and import the certificate. Enter the password you have chosen earlier.
7. Click Next. Choose Place all certificates in the Personal store. Click Next. Click Finish. "The import was successful" message should display.
8. Once you have the certificate import, right click on it and choose Open, this will bring up the Certificate dialog, click the Details tab. You can scroll to the bottom and see the thumbprint property.
We will describe how to upload this certificate to the Windows Azure certificate store later.
1. In Visual Studio, under the just created Cloud Service project, under Roles, select the Web Role, right click on it and click on Properties. Click on the tab for Certificates, and then click on Add Certificate. Click on the … button in the Thumbprint column and select the certificate that was imported in the previous step. Visual Studio will automatically place the thumbprint of the certificate there. Type its name as “xxxazurehost1” as specified above.
This operation automatically updates the following configuration files so that the certificate information will be available in the deployment package: ServiceDefinition.csdef file:
<Certificates>
<Certificate name="xxxazurehost1" storeLocation="LocalMachine" storeName="My" />
</Certificates> ServiceConfiguration.cscfg file:
<Certificate name="xxxazurehost1" thumbprint="80098F3B01810D543751C489F4CFFB54830A2EBD" thumbprintAlgorithm="sha1"/>
</Certificates>
2. Right click on References in the Web Role project and click on Add Reference. Then, browse to the directory for the custom provider PKCS12ProtectedConfigurationProvider.dll and select “Pkcs12CertProtectedConfiguratoinProvider.dll”.
Example path:
C:\<folder>\PKCS12ProtectedConfigurationProvider\PKCS12ProtectedConfigurationProvider\bin\Release\PKCS12ProtectedConfigurationProvider.dll
Right click on the added reference and click on Properties. Set the Copy Local property of the reference to True. You need to do this to deploy the assembly to Windows Azure.
3. The next step is to add and configure the custom protected configuration provider. To do this, add the following <configProtectedData> section to the web.config file just before the <connectionStrings>. Make sure that the thumbprint in the web.config matches the thumbprint value that is received from the Windows Azure Certificate store. The provider needs the thumbprint to decrypt the connection string.
<configProtectedData> <providers> <add name="CustomProvider" thumbprint="80098F3B01810D543751C489F4CFFB54830A2EBD" type="Pkcs12ProtectedConfigurationProvider.Pkcs12ProtectedConfigurationProvider, PKCS12ProtectedConfigurationProvider, Version=1.0.0.0, Culture=neutral, PublicKeyToken=34da007ac91f901d"/> </providers> </configProtectedData>
4. Open the Visual Studio command prompt. Run the following command to encrypt the connectionStrings section by using the custom provider. Note that you should run this command in the folder containing the web.config file:
aspnet_regiis -pef "connectionStrings" "." -prov "CustomProvider"
If the encryption is successful, you will see the following output:
C:\<folder>\DataBinding\WebRole1>aspnet_regiis -pef "connectionStrings" "." -prov "CustomProvider"
Encrypting configuration section...
Succeeded!
When this command runs:
<connectionStrings configProtectionProvider="CustomProvider"> <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#aes192-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>rsaKey</KeyName> \</KeyInfo> <CipherData> <CipherValue>FrhCm9…</CipherValue> </CipherData> </EncryptedKey> </KeyInfo> <CipherData> <CipherValue>VHuKB7…</CipherValue> </CipherData> </EncryptedData> </connectionStrings>
Now, our web.config file includes an encrypted connection string section. As a developer, you are responsible for deploying this web.config file to Windows Azure. You also need to make sure that Windows Azure can decrypt this web.config file properly. That’s why we added the provider assembly (PKCS12ProtectedConfigurationProvider.dl) to the project earlier. Note: When running in the compute emulator environment, if you get an “Keyset does not exist.” error, make sure that your private key is accessible by ASP.NET. To make your private key accessible: 1. Click Start, type mmc in the Search programs and files box, and then press ENTER. 2. On the File menu, click Add/Remove Snap-in. 3. Under Available snap-ins, double-click Certificates. 4. Select Computer account, and then click Next. 5. Click Local computer, and then click Finish. Click OK. 6. Under Console Root, Certificates (Local Computer), in the Personal store, click Certificates. 7. Right-click xxAzurehost1 certificate that has been created earlier. Choose All Tasks > Manage Private Keys. Click Add and then Advanced. Click Locations and choose your local computer. Click Find Now. Select NETWORK SERVICE in the search results and click OK. Click OK. In the Permissions for xxxazurehost1 private keys window, select NETWORK SERVICE and give Read permissions. Click OK.
When you are ready to publish your application, we recommend that you test it in the computer emulator environment first and then create a service package.
1. Build and run the DataBinding ASP.NET application in the computer emulator environment as described at How to: Connect to Windows Azure SQL Database Through ASP.NET.
2. In Solution Explorer, right-click the DataBinding cloud project, and then select Publish.
3. In the Publish Cloud Service dialog window, select Create Service Package Only, and then click OK.
After Visual Studio builds the project and generates the service package, Windows Explorer opens with the current folder set to the location where the generated package is stored. The default directory is C:\<yourfolder>\DataBinding\bin\Debug\Publish. When this package is uploaded to Windows Azure, the web.config file with the encrypted connection string and the PKCS12ProtectedConfigurationProvider.dll assembly will be deployed to Windows Azure as well. This will ensure that the provider will work with the private key in the Windows Certificate store and will be able to decrypt the connection string for the code running on Windows Azure.
Before you can deploy your Windows Azure application, you need to create a hosted service for that deployment.
1. Go to the Windows Azure Management Portal, click Hosted Services, Storage Accounts & CDN in the left pane. Your storage accounts and the associated subscriptions are listed in the middle pane.
2. Click New Hosted Service on the top menu.
3. In the Create a New Hosted Service dialog window, type or select the following values, and then click OK.
DataBindingServiceYourNameHere
As a Windows Azure administrator, you need to upload the private key to Windows Azure.
1. Log into the Windows Azure Management Portal.
2. In the navigation pane, click Hosted Services, Storage Accounts & CDN.
3. In the upper portion of the navigation pane, click Hosted Services.
4. In the services and deployments window, expand the subscription that contains the hosted service that you are adding service certificate to.
5. Expand the hosted service you are adding the certificate to and click on the Certificates folder.
6. On the ribbon, click Add Certificate. This will open the Upload an X.509 Certificate dialog.
7. Click Browse, go to the directory containing your certificate, and click the .PFX file.
8. In Password, type the password of the private key for the certificate.
9. In Retype Password, type the password of the private key for the certificate.
10. Click Create.
11. Click the newly created certificate under Certificates. See the thumbprint value. This should match the thumbprint value specified in your local certificate store. Your hosted service needs this thumbprint value to identify which certificate to use. In addition, this thumbprint value exists in the application’s web.config to notify the custom encryption provider about the certificate that is uploaded to Windows Azure.
A hosted service that is created in Windows Azure can be deployed into one of two different environments; a production environment and a staging environment. A service that is deployed in either of these environments has a DNS name and an IP address assigned to it.
1. Click Hosted Services in the Windows Azure Management Portal.
2. In the middle pane, click DataBinding, the hosted service you just created.
3. Click New Staging Deployment on the top menu.
2. In the middle pane, expand DataBinding, and then click v1.0.0.0.
3. In the Properties pane on the right, click the URL in the DNS name field. The DataBinding ASP.NET application starts in a new browser tab or a new browser window depending on your browser configuration. The DNS name for the staging environment is dynamically generated each time a service is deployed.
4. Test the application.
5. If the application works correctly in the staging environment, you are ready to promote it to the production environment.
3. Click Swap VIP on the top menu.
4. In Swap VIPs dialog window, click OK. Wait until the Status for the deployment changes to Ready.
5. In the Properties pane on the right, make sure that “Status: Succeeded” message shows up in the Last Operation field. Then, you can test the application in the production environment.
6. Click the URL in the DNS name field. The DataBinding ASP.NET application starts in a new browser tab or a new browser window depending on your browser configuration. The DNS name that is associated with the production environment is assigned at runtime and is fixed for the lifetime of the service.
In this article, we have provided an overview of the security fundamentals when working with SQL Database. Then, we listed guidelines and best practices on how to write secure connection strings for SQL Database.
patmas57 edited Revision 21. Comment: Branding updates
Can you provide more detail around the "Keyset does not exist" error? I'm not sure which account you mean when you say "your account". Can you provide the steps to give this account "access rights to run the PKCS12ProtectedConfigurationProvider solution". Thanks - and great article!
Hi, I updated the section and added steps. I hope that helps! Thanks for your feedback!