© Peter A. Carter 2016

Peter A. Carter, Securing SQL Server, 10.1007/978-1-4842-2265-2_5

5. Encryption in SQL Server

Peter A. Carter

(1)Botley, UK

Encryption is a process of obfuscating data with the use of an algorithm that uses keys and certificates. This means that if security is bypassed and data is accessed or stolen by attackers, then it is useless, unless the keys that were used to encrypt it are also acquired. This adds an additional layer of security over and above access control, but it does not replace the requirement for an access control strategy. Encrypting data also has the potential to degrade performance and increase the size of data, so you should use it on the basis of need, as opposed to implementing it on all data as a matter of routine.

This chapter begins with an overview of encryption concepts. You then review the SQL Server encryption hierarchy before a demonstration on how to implement Transparent Data Encryption. The chapter also covers cell-level encryption and Always Encrypted, a technology introduced in SQL Server 2016 that helps isolate encryption keys from the data that they secure.

Generic Encryption Concepts

The following sections introduce the generic encryption concepts of symmetric keys, asymmetric key, certificates, and the Windows Data Protection API.

Defense-in-Depth

Defense-in-depthis a technique used across the IT landscape. It refers to implementing multiple layers of security. For example, a company likely has a perimeter firewall on the outskirts of the network. There may then be further firewalls inside the network, between data centers or network blocks. From the SQL Server perspective, defense-in-depth is achieved by using an encryption strategy to supplement the access control strategy. It does not replace the need for access control, but it does provide an additional layer of defense.

Symmetric Keys

A symmetric keyis an algorithm to encrypt data. It is the weakest form of encryption because it uses the same algorithm for both encrypting and decrypting the data. Although it is the weakest form of encryption, it is also the method that has the least performance overhead. You can encrypt a symmetric key with a password, with another key or with a certificate.

Asymmetric Keys

Unlike a symmetric key, which uses the same algorithm to decrypt or encrypt data, an asymmetric keyuses a pair of keys (algorithms). One of the keys is used only for encryption and the other is used only for decryption. The key that is used to encrypt the data is called the private key and the key that is used to decrypt the data is known as the public key.

Certificates

A certificate is issued by a trusted source, known as a certificate authority (CA) . It uses an asymmetric key, but also provides a digitally signed statement that binds the public key to a principal or device, which holds the corresponding private key.

Self-Signed Certificates

A self-signed certificateis a certificate that has been signed by the same entity that its identity certifies. Self-signed certificates can be created by SQL Server.

Windows Data Protection API

The Windows Data Protection API (DPAPI ) is a cryptographic application programming interface (API) that ships with the Windows operating system. It allows keys to be encrypted by using user secret information or domain secret information. DPAPI is used to encrypt the service master key, which is the top level of the SQL Server encryption hierarchy. The service master key is discussed in the “SQL Server Encryption Concepts” section of this chapter.

SQL Server Encryption Concepts

SQL Server’s cryptography functionality relies on a hierarchy of keys and certificates. The root level of the hierarchy is the service master key. The following sections describe the use of master keys and EKM (Extensible Key Management), as well as SQL Server’s encryption hierarchy.

Master Keys

The root level of the SQL Server encryption hierarchy is the service master key. The service master key is created automatically when the instance is built. It is used to encrypt database master keys, credentials, and the passwords for linked servers by using the DPAPI. The service master key is stored in the master database. There is always one service master key per instance. Since SQL Server 2012, the service master key has been a symmetric key generated using the AES 256 algorithm. Older versions of SQL Server used the Triple DES algorithm.

Tip

When you upgrade an instance from SQL Server 2008 R2 or lower, it is good practice to regenerate the key due to the encryption algorithm used in SQL Server 2012 and higher.

If you need to regenerate the service master key, then all keys within the instance’s encryption hierarchy must be decrypted and then re-encrypted. This means that every key and certificate that is encrypted directly or indirectly from the master key must be regenerated. This is a very resource-intensive process and should only be attempted during a maintenance window .

You can regenerate the service master key using the command in Listing 5-1. You should be aware that if the process fails to decrypt and re-encrypt any key that is below it in the hierarchy, then by default, the whole regeneration process fails. You can change this behavior by using the FORCE keyword, which forces the process to continue after errors.

Caution

Be warned that using the FORCE keyword leaves any data that cannot be decrypted and re-encrypted unusable. There is no way to regain access to this data.

Listing 5-1. Regenerate the Service Master Key
ALTER SERVICE MASTER KEY REGENERATE ;

Because the service master key is crucial, it is very important to back it up after building a new instance and after the key is regenerated. You should then store the backup in a secure offsite location, so that it is available in disaster recovery scenarios. You can also restore the backup of this key when you migrate an instance to a different server to avoid issues with the encryption hierarchy. The script in Listing 5-2 demonstrates how to back up and restore the service master key. If the master key you restore is identical, then SQL Server lets you know and data does not need to be decrypted and re-encrypted.

Tip

If your instance does not use any encryption features, then a backup of the service master key is not required.

Listing 5-2. Back up and Restore the Service Master Key
--Backup Service Master Key

BACKUP SERVICE MASTER KEY
TO FILE = 'c:keysservice_master_key'
ENCRYPTION BY PASSWORD = 'Pa$$w0rd' ;


--Restore Service Master Key

RESTORE SERVICE MASTER KEY
FROM FILE = 'c:keysservice_master_key'
DECRYPTION BY PASSWORD = 'Pa$$w0rd ' ;
Tip

service_master_key is the name of the key file, not a folder. By convention, it does not have an extension. If you are following along with the demonstrations, then remember to change the filepath to match your own configuration.

A database master key is a symmetric key, encrypted using the AES 256 algorithm. The service master key is used to encrypt private keys and certificates that are stored within a database. It is encrypted using a password as the secret; but a copy is created, which is encrypted using the service master key. This allows the service master key to be opened automatically when required. If this copy does not exist, then you need to open it manually.

If the copy does not exist or is corrupt, the key needs to be explicitly opened in order for you to use a key that is below it in the hierarchy (a key that has been encrypted, using the service master key). Copies of the service master key are stored within the database and the master database.

It is as important to back up a service master key as it is to back up a service master key, because losing the key results in data loss for any data that is below it in the encryption hierarchy. In some cases, this could be an entire database. The script in Listing 5-3 demonstrates how to create a service master key for the AdventureWorks2016 database. It then backs up the key and attempts to restore it. The FORCE keyword can be used for service master keys in the same way it can be used for a service master key. This keyword forces the decrypt and re-encrypt process to continue on error. There is a possibility of data loss, however.

Tip

If you are following along with the examples, remember to change the filepath to match your own configuration.

Listing 5-3. Administering a Database Master Key
USE AdventureWorks2016                                                
GO


CREATE MASTER KEY ENCRYPTION BY PASSWORD = 'Pa$$w0rd' ;

BACKUP MASTER KEY TO FILE = 'c:keysChapter5_master_key'
ENCRYPTION BY PASSWORD = 'Pa$$w0rd';


RESTORE MASTER KEY
FROM FILE = 'c:keysChapter5_master_key'
DECRYPTION BY PASSWORD = 'Pa$$w0rd' --The password in the backup file
ENCRYPTION BY PASSWORD = 'Pa$$w0rd' ; --The password it will be encrypted within the
database

EKM and Key Stores

An Extensible Key Management (EKM ) module allows you to generate and manage keys and certificates used to secure SQL Server data within a third-party hardware security module (HSM) . The EKM module provides the interface with SQL Server by using the Microsoft Cryptographic API (MS-CAPI) . This is more secure because the key is not being stored with the data. It also means that you can benefit from advanced features that may be offered by a third-party vendor, such as key rotation and secure key disposal. When using an HSM, you may also witness improved performance because the encryption and decryption of keys are hardware-based.

Key stores provide secure storage and a trusted source for keys and certificates. Windows Certificate Store provides the functionality within your own Windows Server enterprise. Azure Key Vault offers key storage within Windows Azure. There are also third-party and open source key store providers, such as Amazon Key Management Services (which is a service within the Amazon Web Services ecosystem), KeyWhiz, and Vault, to name but a few.

SQL Server Encryption Hierarchy

Figure 5-1 illustrates the encryption hierarchy in SQL Server.

A395795_1_En_5_Fig1_HTML.jpg
Figure 5-1. SQL Server encryption hierarchy

Encrypting Data

Data can be encrypted in SQL Server by using either a password or the encryption hierarchy. The following sections discuss each of these approaches.

Encrypting Data with a Password or a Passphrase

The most basic level of encrypting data in SQL Server is the ENCRYPTBYPASSPHRASE()function, which allows you to encrypt data by directly using a password or a passphrase, rather the SQL Server encryption hierarchy.

To illustrate this, let’s look at the Sales.CreditCard table in the AdventureWorks2016 database. This table stores information on customers’ credit card information in plain text, which is not a great idea from a security perspective and it may also be against regulatory requirements on data protection.

Imagine that the company’s compliance department has noticed this issue during an audit and has tasked you with encrypting the credit card number column. To encrypt this column, you need to perform the following tasks:

  • Create a new column of type VARBINARY

  • Encrypt the values in the CardNumber column and insert them into the new column

  • Drop the original column

  • Update queries and ETL processes to use the new column

Tip

If you have been following the examples in previous chapters, then you should remove dynamic data masking from the CardNumber column before continuing. This can be achieved with the script in Listing 5-4.

Listing 5-4. Drop Dynamic Data Mask
USE AdventureWorks2016
GO


ALTER TABLE Sales.CreditCard   
ALTER COLUMN CardNumber DROP MASKED ;  

The first task is to add a new column to the table. This can be achieved using the script in Listing 5-5. Because the column initially has no values and there is no DEFAULT constraint, you should allow NULL values. This can be changed once the column is populated.

Listing 5-5. Add a New Column to Hold the Encrypted Credit Card Numbers
USE AdventureWorks2016
GO


ALTER TABLE Sales.CreditCard ADD
        CardNumberEncrypted varbinary(8000) NULL ;

The next task is to populate the new column. To achieve this, encrypt the values of the CardNumber column, using the ENCRYPTBYPASSPHRASE() function. This function accepts the parameters described in Table 5-1.

Table 5-1. ENCRYPTBYPASSPHRASE() Parameters

Parameter

Description

passphrase

The password or phrase to generate a symmetric key.

cleartext

The value to be encrypted.

add_authenticator

Specifies if an authenticator should be used.

authenticator

The value to be used to derive an authenticator.

The script in Listing 5-6 demonstrates how the CardNumberEncrypted column can be populated.

Listing 5-6. Populate the Encrypted Column
  UPDATE Sales.CreditCard
  SET CardNumberEncrypted = ENCRYPTBYPASSPHRASE('Pa$$w0rd', CardNumber, 0) ;

You can now set the CardNumberEncrypted column to not allow NULL values and to drop the original column. This is demonstrated in Listing 5-7.

Tip

Do not run the script in Listing 5-7 if you plan to follow further examples in this chapter, because you are reusing the CardNumber column.

Listing 5-7. Set Encrypted Column NOT NULL and Drop Original Column
--Set CardNumberEncrypted column to be NOT NULL
ALTER TABLE Sales.CreditCard
ALTER COLUMN CardNumberEncrypted VARBINARY(256) NOT NULL ;


--Do not run following section, if you plan to follow later examples

DROP INDEX AK_CreditCard_CardNumber ON Sales.CreditCard ;
GO


ALTER TABLE Sales.CreditCard
        DROP COLUMN CardNumber ;

Changing ETL processes and queries depends on how your database is being used, of course. The AdventureWorks2016 database is an OLTP database, so it is likely that credit card numbers are updated either by salespeople, or by customers directly, as opposed to via ETL process. There may be downstream ETL processes, however, which move the data into a data warehouse or archived database.

Let’s assume that there is a stored procedure that was previously used to return customers’ credit card information from a web portal. This fictional stored procedure is shown in Listing 5-8. Assume that the user’s BusinessEntityID has been determined elsewhere in the front-end app based upon login information.

Listing 5-8. Return Credit Card Information
CREATE PROCEDURE ReturnCredCardInfo @BusinessEntityID INT
AS
BEGIN
        SELECT p.BusinessEntityID, p.firstName, p.LastName, cc.CardNumber, cc.CardType, cc.ExpMonth, cc.ExpYear
        FROM Person.Person p
        INNER JOIN Sales.PersonCreditCard pcc
                ON p.BusinessEntityID = pcc.BusinessEntityID
                INNER JOIN Sales.CreditCard cc
                        ON pcc.CreditCardID = cc.CreditCardID
        WHERE p.BusinessEntityID = @BusinessEntityID ;
END

To work with the new, encrypted column, you need to modify the stored procedure to use the DECRYPTBYPASSPHRASE() function. This function accepts the parameters described in Table 5-2.

Table 5-2. DECRYPTBYPASSPHRASE() Parameters

Parameter

Description

passphrase

The password or phrase to decrypt the data.

ciphertext

The value to be decrypted.

add_authenticator

Specifies whether an authenticator is required to decrypt the data.

authenticator

The authenticator data.

The script in Listing 5-9 demonstrates how to rewrite the procedure. Note that in addition to decrypting the column, you must also convert the result back to an NVARCHAR value for meaningful results to be returned. You know that 25 characters is sufficient for the NVARCHAR value, because it is the length of the original CardNumber column.

Listing 5-9. Modify the Procedure to Work with the Encrypted Column
ALTER PROCEDURE ReturnCredCardInfo @BusinessEntityID INT
AS
BEGIN
        SELECT p.BusinessEntityID
                , p.firstName
                , p.LastName
                , CONVERT(NVARCHAR(25),
                        DECRYPTBYPASSPHRASE('Pa$$w0rd',cc.CardNumberEncrypted, 0)
                  )
                ,  cc.CardType
                , cc.ExpMonth
                , cc.ExpYear
        FROM Person.Person p
        INNER JOIN Sales.PersonCreditCard pcc
                ON p.BusinessEntityID = pcc.BusinessEntityID
                INNER JOIN Sales.CreditCard cc
                        ON pcc.CreditCardID = cc.CreditCardID
        WHERE p.BusinessEntityID = @BusinessEntityID ;
END

This approach still leaves a security hole, however. The data is decrypted by the application, so although the user may not have the permissions to see some data, all of the data is decrypted. This is appropriate in some scenarios, such as when a sales team manages credit card information and customers do not have direct access to the application .

Imagine a scenario, however, where you want users to be able to manage their own credit card information. In this instance, you might want to ensure that all data remains encrypted, except for a user’s own credit card number.

To implement this strategy, when a user inputs his credit card information, it is encrypted using the password that the customer uses to log in to the application. The front-end application can simply pass the credit card number and the user’s password to a stored procedure, via parameters. Listing 5-10 describes two stored procedures. The first can be used by the front-end application to add a new credit card. The second returns the credit card number. Notice that the ENCRYPTBYPASSPHRASE() and DECRYPTBYPASSPHRASE() functions accept variables as parameters, as well as hard-coded strings.

Listing 5-10. Encrypt and Decrypt Data Based Upon a User’s Password
USE AdventureWorks2016
GO
CREATE PROCEDURE dbo.AddCreditCard
                                        @BusinessEntityID         INT
                                        ,@CreditCardNumber        NVARCHAR(25)
                                        ,@CardType                NVARCHAR(50)
                                        ,@ExpMonth                TINYINT
                                        ,@ExpYear                 SMALLINT
                                        ,@Password                NVARCHAR(128)
AS
BEGIN
        DECLARE @CreditCardID        INT ;
        BEGIN TRANSACTION
                INSERT INTO Sales.CreditCard
                                ( CardType ,
                                  ExpMonth ,
                                  ExpYear ,
                                  ModifiedDate,
                                  CardNumberEncrypted
                                )
                VALUES  ( @CardType,
                                  @ExpMonth,
                                  @ExpYear,
                                  SYSDATETIME(),
                                  ENCRYPTBYPASSPHRASE(@Password, @CreditCardNumber, 0)
                                ) ;
                SET @CreditCardID = @@IDENTITY ;


                INSERT INTO Sales.PersonCreditCard
                                ( BusinessEntityID ,
                                  CreditCardID ,
                                  ModifiedDate
                                )
                VALUES  ( @BusinessEntityID,
                                  @CreditCardID,
                                  SYSDATETIME()
                                ) ;
        COMMIT
END
GO


CREATE PROCEDURE ReturnCredCardInfo
                                        @BusinessEntityID        INT
                                        ,@Password               NVARCHAR(128)
AS
BEGIN
        SELECT
                CONVERT(NVARCHAR(25), DECRYPTBYPASSPHRASE(@Password,cc.CardNumberEncrypted, 0)) AS CreditCardNumber
        FROM Person.Person p
        INNER JOIN Sales.PersonCreditCard pcc
                ON p.BusinessEntityID = pcc.BusinessEntityID
                INNER JOIN Sales.CreditCard cc
                        ON pcc.CreditCardID = cc.CreditCardID
        WHERE p.BusinessEntityID = @BusinessEntityID ;
END
GO

Encrypting Data with Keys and Certificates

When encrypting data using the SQL Server encryption hierarchy, data can be encrypted using a symmetric key, an asymmetric key, or a certificate. Table 5-3 describes the functions that are exposed by SQL Server for encrypting and decrypting data using keys and certificates.

Table 5-3. Cryptographic Functions

Encryption Type

Encryption Function

Decryption Function

Symmetric

ENCRYPTBYKEY()

DECRYPTBYKEY()

Asymmetric

ENCRYPTBYASYKEY()

DECRYPTBYASYKEY()

Certificate

ENCRYPTBYCERT()

DECRYPTBYCERT()

Tip

Keys and certificates within the hierarchy can be encrypted using further keys and certificates.

Tip

  For performance reasons, you should always use a symmetric key, unless there is a very good reason (usually a regulatory requirement) not to.

To demonstrate how to encrypt data using a symmetric key, you first create a certificate. You then create a symmetric key, which is encrypted using this new certificate, in the AdventureWork2016 database. Next, you update the CreditCardNumberEncrypted column so that the credit card numbers are encrypted using this symmetric key, as opposed to a passphrase.

The CREATE CERTIFICATE T-SQL statement accepts the arguments described in Table 5-4 when being used to generate a new key .

Table 5-4. CREATE CERTIFICATE Arguments

Argument

Description

AUTHORIZATION

Specifies the owner of the certificate.

ACTIVE FOR BEGIN_DIALOG

Specifies if the certificate can be used to initiate a Service Broker conversation.

ENCRYPTION BY PASSWORD

Specifies the password that is used to encrypt the certificate’s private key.

WITH SUBJECT

Specifies a subject for the certificate.

START_DATE

Specifies a date on which the certificate becomes valid.

EXPIRY_DATE

Specifies a date on which the certificate expires, after which it is no longer valid.

Tip

The CREATE CERTIFICATE statement can also be used to import a certificate that is stored within an assembly or to create a certificate that uses existing keys stored within a file. For information on the available arguments when using these options, please refer to https://msdn.microsoft.com/en-us/library/ms187798.aspx .

The CREATE SYMMETRIC KEY T-SQL statement accepts the arguments described in Table 5-5.

Table 5-5. CREATE SYMMETRIC KEY Arguments

Argument

Description

AUTHORIZATION

Specifies the owner of the key.

FROM PROVIDER

If the key is managed by an EKM provider, specifies the EKM provider to use.

KEY_SOURCE

Specifies a passphrase from which to generate the key.

IDENTITY_VALUE

Specifies a value from which to generate a GUID that can be used for temporary tagging data that is encrypted with a temporary key.

PROVIDER_KEY_NAME

Specifies the name by which the key is known to the EKM provider (if one is used).

CREATION_DISPOSITION

If an EKM provider is used, specifies if a new key should be created in the EKM or if an existing key should be used. The following are acceptable values:

•   CREATE_NEW: Specifies that a new key is created in the EKM provider.

•   OPEN_EXISTING: Specifies that an existing key is opened in the EKM provider.

ENCRYPTION BY

Specifies how the key is encrypted. The following are acceptable values:

•   CERTIFICATE (followed by the name of the certificate)

•   PASSWORD (followed by the password to use)

•   SYMMETRIC KEY (followed by the name of the key to use)

•   ASYMMETRIC KEY (followed by the name of the key to use)

ALGORITHM

Specifies the algorithm to encrypt the key. The following are acceptable values:

•   DES

•   TRIPLE_DES

•   TRIPLE_DES_3KEY

•   RC2

•   RC4

•   RC4_128

•   DESX

•   AES_128

•   AES_192

•   AES_256

The ENCRYPTBYKEY() function accepts the parameters described in Table 5-6.

Table 5-6. ENCRYPTBYKEY() Parameters

Parameter

Description

key_GUID

The GUID of the key that is used to encrypt the data.

cleartext

The value to be encrypted.

add_authenticator

Specifies if an authenticator should be used.

authenticator

The value to be used to derive an authenticator.

Listing 5-11 demonstrates how to create the symmetric key and use it to encrypt the CardNumberEncrypted column. Notice that you need to open the key before you use it. You then close the key after you have completed the activity .

Listing 5-11. Encrypt Data with a Symmetric Key
USE AdventureWorks2016
GO


--Create the certificate
CREATE CERTIFICATE CreditCardCert
WITH SUBJECT = 'Credit Card Numbers';
GO


--Create the symmetric key
CREATE SYMMETRIC KEY CreditCardKey
WITH ALGORITHM = AES_128
ENCRYPTION BY CERTIFICATE CreditCardCert;


--Open the key
OPEN SYMMETRIC KEY CreditCardKey
DECRYPTION BY CERTIFICATE CreditCardCert;


--Encrypt the data, using the symmetric key
UPDATE Sales.CreditCard
        SET CardNumberEncrypted = ENCRYPTBYKEY(Key_GUID('CreditCardKey'), CardNumber);


--Close the key
CLOSE SYMMETRIC KEY CreditCardKey ;

Data encrypted with a symmetric key can be decrypted using the DECRYPTBYKEY() function. This function accepts the parameters described in Table 5-7.

Table 5-7. DECRYPTBYKEY() Parameters

Parameter

Description

ciphertext

The value to be decrypted.

add_authenticator

Specifies if an authenticator is required to decrypt the data.

authenticator

The authenticator data.

The script in Listing 5-12 demonstrates how to use the DECRYPTBYKEY() function to read the CardNumberEncrypted column. Notice that you once again need to open and close the key .

Listing 5-12. Decrypt Data With DECRYPTBYKEY()
USE AdventureWorks2016
GO


--Open the key
OPEN SYMMETRIC KEY CreditCardKey
DECRYPTION BY CERTIFICATE CreditCardCert;


--Decrypt the data, using the symmetric key
SELECT CONVERT(NVARCHAR(30), DECRYPTBYKEY(CardNumberEncrypted)) AS CreditCardNumber
FROM Sales.CreditCard ;


--Close the key
CLOSE SYMMETRIC KEY CreditCardKey ;

Transparent Data Encryption

When implementing a security strategy for your sensitive data, one important aspect to consider is the risk of data being stolen. Imagine a situation in which a privileged user with malicious intent uses detach/attach to move a database to a different instance, which they have created and therefore have sysadmin access to. The result is the user having permissions to data that they are not authorized to view.

Another potential scenario to consider is a malicious user gaining access to a backup of a database that contains data that he is not authorized to view. The user restores the backup file to an instance that he has created and has sysadmin access, and suddenly, he has the permissions to access the confidential data.

Transparent Data Encryption (TDE) protects against both of these scenarios by encrypting all data pages and the log file of a database. Data is encrypted using a symmetric key called the database encryption key. This key is stored in the boot record of the database and encrypted using a server certificate stored within the master database. This means that if the database is stolen, it cannot be decrypted, because the key used to decrypt it is stored in a different database.

Caution

Obviously, if the master database or a backup of the server certificate is also stolen, then the data could be decrypted.

After you have enabled TDE on a database, the data and log pages are encrypted before they are written to disk. They are decrypted when they are read into memory. This means that the encryption is transparent to users, and applications do not need to be modified in order to access the data.

TDE also provides several other advantages over the encryption of data within columns. First, it does not cause bloat. A database encrypted with TDE is the same size that it was before it was encrypted. Also, although there is performance overhead, this is significantly less than the performance overhead that is caused cell-level encryption. The fact that developers do not need to modify their code to use TDE is another significant advantage in itself because it improves time-to-market (both for implementing TDE and for future application enhancements).

Considerations for TDE with Other Technologies

When planning the implementation of TDE, be mindful of how it interacts with other technologies. For example, you are able to encrypt a database that uses In-Memory OLTP , but the data within the In-Memory filegroup is not encrypted—even when data is persisted alongside the schema.

Tip

Even though the memory optimized data is not encrypted, log records associated with in-memory transactions are encrypted.

It is also possible to encrypt databases that use FILESTREAM, but again, data within a FILESTREAM filegroup is not encrypted. If you use full-text indexes, new full-text indexes are encrypted. Existing full-text indexes are only encrypted after they are imported during an upgrade.

Caution

Using full-text indexing with TDE, is not a good practice because data is written to disk in plain text during the full-text indexing scan operation. This leaves a window of opportunity for attackers to access sensitive data.

If your database is replicated, then it is important to manually enable TDE on the subscribers. This is because replication does not automatically send the data from a TDE-encrypted database to the subscribers in an encrypted form.

Due to the nature of TempDB, this system database is always encrypted using TDE, if any user database on the instance has TDE enabled. This stops potential attackers from stealing data at rest while it is spooled to TempDB or stored in a temporary table, and so forth. It does mean, however, that databases on the instance that are not enabled for TDE may still notice a performance penalty, which is caused by TDE.

TDE is incompatible with instant file initialization. Instant file initialization speeds up operations that create or expand files, because the files do not need to be zeroed out. If your instance is configured to use instant file initialization, then it no longer works for any files that are associated with any databases that you encrypt with TDE. This is because of a hard technical requirement for files to be zeroed out when TDE is enabled on a database.

Files used by buffer cache extensions are not encrypted by TDE. If you wish to encrypt the files associated with buffer cache extensions, then you must use system-level encryption tooling.

Implementing TDE

Implementing Transparent Data Encryption involves the following steps:

  1. Create a service master key for the master database (If one does not already exist).

  2. Create a certificate or asymmetric key in the master database .

  3. Create a database encryption key in the database that you wish to encrypt.

  4. Alter the database to enable Transparent Database Encryption.

Note

The certificate or asymmetric key must be encrypted using the service master key in the master database. If you encrypt the certificate by password only, then SQL Server will not allow you to use it to encrypt the database encryption key.

Tip

An asymmetric key can only be used if it is managed by an EKM.

When you enable TDE for a database, a background process moves through each page in every data file and encrypts it. This does not make the database inaccessible, but it does take out locks, which stop maintenance operations from taking place. While the encryption scan is in progress, the following operations cannot be performed:

  • Dropping a file

  • Dropping the database

  • Taking the database offline

  • Detaching a database

  • Setting a database or filegroup as READ_ONLY

The operation to enable TDE will fail if any of the filegroups within a database are marked as READ_ONLY. This is because all pages within all files need to be encrypted when TDE is enabled, and this process involves changing the data within the pages to obfuscate them.

The script in Listing 5-13 follows the steps required to encrypt the AdventureWorks2016 database. The arguments accepted by the CREATE DATABASE ENCRYPTION KEY statement are described in Table 5-8.

Table 5-8. CREATE DATABASE ENCRYPTION KEY Arguments

Argument

Description

WITH ALGORITHM

Specifies the algorithm that should be used by the database encryption key. Acceptable values are as follows:

•   AES_128

•   AES_192

•   AES_256

•   TRIPLE_DES_3KEY

ENCRYPTION BY SERVER

Specifies the certificate or asymmetric key that is used to encrypt the database encryption key. Acceptable values are as follows:

•   CERTIFICATE (followed by the name of the certificate to use)

•   ASYMMETRIC KEY (followed by the name of the asymmetric key to use)

Listing 5-13. Encrypt the AdventureWorks2016 Database
USE Master
GO


Create the Database Master Key (if it does not already exist)

CREATE MASTER KEY ENCRYPTION BY PASSWORD = 'Pa$$w0rd';
GO


--Create the Server Certificate

CREATE CERTIFICATE TDECert WITH SUBJECT = 'Certificate For TDE';
GO


USE AdventureWorks2016
GO


--Create the Database Encryption Key

CREATE DATABASE ENCRYPTION KEY
WITH ALGORITHM = AES_128
ENCRYPTION BY SERVER CERTIFICATE TDECert ;
GO


--Enable TDE on the database

ALTER DATABASE AdventureWorks2016
SET ENCRYPTION ON ;
GO

Administering TDE

When working with TDE-encrypted databases, there are administrative scenarios that you should be aware of. These are discussed in the following sections.

Backing up the Certificate

When configuring TDE, you are given a warning that the certificate used to encrypt the database encryption key has not been backed up. Backing up this certificate is critical and you should do so before you configure TDE or immediately afterward. If the certificate becomes unavailable, you have no way to recover the data within your database. You can back up the certificate by using the script in Listing 5-14.

Listing 5-14. Backing up the Certificate
BACKUP CERTIFICATE TDECert
TO FILE = 'C:certificatesTDECert'
WITH PRIVATE KEY (file='C:certificatesTDECertKey',
ENCRYPTION BY PASSWORD='Pa$$w0rd') ;

Migrating an Encrypted Database

Once TDE is enabled on a database, an attempt to attach or restore the database to a new instance will fail. Therefore, if you need to migrate a TDE-encrypted database to a new instance, you need to take the cryptographic artifacts into account.

Before migrating a database to a new instance, you must first create a service master key with the same password, and then restore the server certificate and private key to the new instance. You can restore the server certificate that you created earlier by using the script in Listing 5-15.

Listing 5-15. Preparing for a Database Migration
CREATE MASTER KEY ENCRYPTION BY PASSWORD = 'Pa$$w0rd' ;
GO
CREATE CERTIFICATE TDECert
FROM FILE = 'C:CertificatesTDECert'
WITH PRIVATE KEY
(
FILE = 'C:CertificatesTDECertKey',
DECRYPTION BY PASSWORD = 'Pa$$w0rd'
) ;
Tip

Make sure that the SQL Server service account has permissions to the certificate and key files in the operating system; otherwise, you will receive an error stating that the certificate is not valid, does not exist, or that you do not have permissions to it. This means that you should check the restore immediately and periodically repeat the test.

Always Encrypted

Always Encrypted is a new technology introduced in SQL Server 2016. It is the first SQL Server encryption technology that protects data against privileged users, such as members of the sysadmin role. Because DBAs cannot view the encrypted data, Always Encrypted provides true segregation of duties. This can help with compliance issues for sensitive data when your platform support is outsourced to a third-party vendor. This is especially true if you have a regulatory requirement not to make your data available outside of your country’s jurisdiction and the third-party vendor is using offshore teams.

Always Encrypted uses two separate types of keys: a column encryption keyand a column master key. The column encryption key is used to encrypt the data within a column and the column master key is used to encrypt the column encryption keys.

Tip

The column master key is a key or a certificate located within an external store.

Having the second layer of key means that SQL Server needs only to store an encrypted value of the column encryption key ; it does not need to store it in plain text. The column master key is not stored in the database engine at all. Instead, it is stored in an external key store. The key store used could be an HSM (hardware security module), Windows Certificate Store, or an EKM provider, such as Azure Key Vault or Thales. SQL Server then stores the location of the column master key within the database metadata.

Instead of SQL Server being responsible for the encryption and decryption of data, this responsibility is handled by the client driver. Of course, this means that the application must be using a supported driver. See https://msdn.microsoft.com/en-gb/library/mt147923.aspx for information on working with supported drivers.

When an application issues a request that requires data to either be encrypted or decrypted, the client driver liaises with the database engine to determine the location of the column master key. The database engine also provides the encrypted column encryption key and the algorithm used to encrypt it.

The client driver can now contact the external key store and retrieve the column master key, which it uses to decrypt the column encryption key. The plain text version of the column encryption key can then be used to encrypt or decrypt the data, as required.

The entire process is transparent to the application, meaning that changes are not required to the application’s code in order to use Always Encrypted. The only change that may be required is to use a later supported driver.

Note

The client driver caches the plain text version of column encryption keys as an optimization, which attempts to avoid repeated round trips to the external key store.

The diagram in Figure 5-2 depicts the high-level architecture of Always Encrypted.

A395795_1_En_5_Fig2_HTML.jpg
Figure 5-2. Always Encrypted architecture

Implementing Always Encrypted

When implementing Always Encrypted, the creation of tables with encrypted columns and the creation of key metadata are supported in T-SQL, PowerShell, or via the SSMS GUI. Other activities, however, such as provisioning keys and the actual encryption of data are only supported in PowerShell or via the SSMS GUI. They cannot currently be achieved with T-SQL. Therefore, this section demonstrates how to configure Always Encrypted via SSMS.

You will use Always Encrypted to secure the CreditCardNumber, ExpMonth, and ExpYear columns of the Sales.CreditCard table of the AdventureWorks2016 database. To achieve this, the first step is to create a column master key . You will use the Windows Certificate Store to store this key.

Tip

If you are following along with the demonstrations in this chapter, you should delete the Sales.usp_InsertSalesOrder_inmem stored procedure before continuing. This is a natively compiled stored procedure, which is not supported by Always Encrypted.

In Object Explorer, drill though Databases ➤ AdventureWorks2016 ➤ Security ➤ Always Encrypted Keys and select New Column Master Key from the context menu of the Column Master Keys node. This causes the New Column Master Key dialog box to be invoked, as illustrated in Figure 5-3.

A395795_1_En_5_Fig3_HTML.jpg
Figure 5-3. New Column Master Key dialog box

In this dialog box, you enter a name for the column master key and then selected the type of store that the key is stored in from the Key Store drop-down list. Table 5-9 describes all possible values for Key Store. You can choose an existing key or certificate, or alternatively use the Generate Certificate button to create a self-signed certificate in the appropriate store to use as the column master key . In this example, a self-signed certificate was generated.

Table 5-9. Key Store Values

Key Store Type

Description

Windows Certificate Store - Current User

The key or certificate is stored in the area of the Windows Certificate Store that is reserved for the profile of the user that created the certificate. This option may be appropriate if you use the database engine’s service account interactively to create the certificate.

Windows Certificate Store - Local Machine

The key or certificate is stored in the area of the Windows Certificate Store that is reserved for the local machine.

Azure Key Vault

The key or certificate is stored in the Azure Key Vault EKM service.

Key Storage Provider (CNG)

The key or certificate is stored in an EKM store that supports Cryptography API: Next Generation.

If you generate the certificate, as opposed to selecting an existing certificate, it immediately appears within the chosen key store. For example, Figure 5-4 shows the certificate within the Current User area of the Windows Certificate Store.

A395795_1_En_5_Fig4_HTML.jpg
Figure 5-4. Windows Certificate Store

Now that the column master key has been created, you can generate a column encryption key . To do this, you select New Column Encryption Key from the context menu of the Databases ➤ AdventureWorks2016 ➤ Security ➤ Always Encrypted Keys ➤ Column Encryption Keys node in Object Explorer. This causes the New Column Encryption Key dialog box to be invoked, as illustrated in Figure 5-5.

A395795_1_En_5_Fig5_HTML.jpg
Figure 5-5. New Column Encryption Key dialog box

In this dialog box, you have entered a name for the column encryption key and selected the appropriate column master key from the drop-down list.

The final step is to encrypt the CreditCardNumber, ExpMonth, and ExpYear columns. When encrypting the data, you have a choice of two methods: deterministic or randomized. This is an important decision to understand, as it may have an impact of performance as well as security.

Deterministic encryption always produces the same encrypted value for the same plain text value. This means that if deterministic encryption is used, operations—including equality joins, grouping and indexing—are possible on an encrypted column. This leaves the possibility of attacks against the encryption, however.

If you use randomized encryption, then different encrypted values can be generated for the same plain text values. This means that while encryption loopholes are plugged, equality joins, grouping, and indexing are not supported against the encrypted data.

You will use deterministic encryption because you expect the columns to have a high cardinality. You will again use SSMS for this action because T-SQL only has support for encrypting data in new columns, not existing columns. The process of encrypting the data includes changing the column collation to BIN2, because this is the only collation currently supported by Always Encrypted.

Caution

Data should be encrypted during a maintenance window. DML statements against the table while encryption is in progress could potentially result in data loss.

To invoke the Always Encrypted wizard for the CardNumber column, drill though Databases ➤ AdventureWorks2016 ➤ Tables in Object Explorer. Select Encrypt Columns from the context menu of the Sales.CreditCard table. After passing through the welcome page of the wizard, the Column Selection page is displayed, as illustrated in Figure 5-6.

A395795_1_En_5_Fig6_HTML.jpg
Figure 5-6. Column selection page

On this page, you first use the check boxes on the left-hand side to select the columns that you want to encrypt. You then have a choice of selecting an encryption key for each column individually, or using the check box and drop-down list at the top of the page to choose a single key that is used to encrypt all selected columns. You have used the latter option. Finally, you need to specify if each column should be encrypted using deterministic or randomized encryption.

The warning next to the CardNumber column is informing you that the column’s collation is changed to the supported BIN2 collation. It is not possible to select the DateModified column because there is a default constraint on the column. This is not supported by Always Encrypted.

The Master Key Configuration page simply informs you that no further configuration is required. If you had chosen to create new column encryption key s on the Column Selection page, then you could use this page to associate the new keys with a column master key .

The Run Settings page provides an option for performing the encryption immediately or scripting the action out to PowerShell. The Summary page provides an overview of the actions to be performed. After clicking the Finish button on the Summary page, the encryption is performed. The Results page should be reviewed for success status.

Always Encrypted Limitations

Not all features are supported by Always Encrypted. You should check the columns for compatibility before planning your encryption strategy. The following data types are not supported:

  • XML

  • TIMESTAMP

  • ROWVERSION

  • IMAGE

  • NTEXT

  • TEXT

  • SQL_VARIANT

  • HIERARCHYID

  • GEOGRAPHY

  • GEOMETRY

The following features are also not fully supported:

  • User defined-types are not supported

  • FILESTREAM columns are not supported

  • Columns with the ROWGUIDCOL property specified are not supported

  • String columns are only supported when they use a BIN2 collation

  • Clustered and non-clustered and full-text index key columns are only supported for deterministic encryption

  • Columns referenced by computed columns are only supported when the expression does not perform unsupported operations

  • Sparse column sets are not supported

  • Columns that are referenced by statistics are not supported

  • Columns using alias data types are not supported

  • Partitioning key columns are not supported

  • Columns with default constraints are not supported

  • Columns referenced by unique constraints are only supported for deterministic encryption

  • Primary key columns are only supported when both of the following are true:

    • Deterministic encryption is used

    • Change tracking is not implemented on the column

  • Referencing columns in foreign keys are only supported when both of the following are true:

    • Deterministic encryption is used

    • The referenced and referencing columns are encrypted using the same key

  • Columns referenced by check constraints are not supported

  • Columns in tables that use change data capture are not supported

  • Columns that are masked using Dynamic Data Masking are not supported

  • Columns in existing Stretch Database tables cannot be encrypted. However, tables can be enabled for stretch, after their columns are encrypted with Always Encrypted.

  • Columns in external PolyBase tables are not supported

  • Columns in table variables

Summary

SQL Server 2016 provides an array of encryption options that DBAs can use to provide defense-in-depth. The encryption technologies make use of the encryption hierarchy. This starts with the service master key, which is encrypted by the Windows DPAPI and then used to encrypt service master keys. The service master keys are then used to encrypt keys and certificates.

Data can be encrypted at rest by using a passphrase, a combination of keys, and certificates within the encryption hierarchy. Keys and certificates stored in external key vaults are also supported through EKM integration. This method of encryption allows specific columns to be encrypted, but can cause significant bloat as well as performance implications. Applications and ETL processes need to be modified to access the encrypted data.

Transparent Data Encryption provides a low overhead method of encrypting data at rest. As the name suggests, TDE is transparent to applications, so no changes are required to applications or ETL processes in order to access the encrypted data. TDE protects your organization against the theft of a database or a backup file; however, any user with privileges to access data is able to decrypt the data.

Always Encrypted is a new technology introduced in SQL Server 2016. It allows the separation of roles and responsibilities. It is the first SQL Server encryption technology that prevents data from being accessed by highly privileged users, such as DBAs. Always Encrypted provides encryption for data, both at rest and in transit, as the data is decrypted by the client driver. Because SQL Server does not store the plain-text version of the encryption keys, even privileged users cannot decrypt the data. This is especially useful when outsourcing platform support to third parties.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset