How To Get Started With Always Encrypted For Beginners - Part Three

A few weeks ago, I wrote Parts 1 and 2 of this series, which was a beginner’s guide to Always Encrypted. In part 3, I am going to go over what roadblocks I ran into when trying to implement this solution for a client. The goal of the project was to prevent the DBA from being able to view salary information, while still allowing the application to function without issue.

We were able to encrypt the data easily, but the entire process was not without issues. We had to remove default constraint values to get it to implement. Always Encrypted does not currently support constraints. Fortunately, the default zero value they had in place was easily fixed and we were off and running. Select statements from SSMS were returning encrypted values, and the application was able to read the encrypted values and return the real values.

The real challenges started when the client began to test their application code. The first thing we hit was triggers.

Bam

The table had several insert triggers associated with the columns that were now encrypted. Since the data was now encrypted the insert triggers would fail. Again, we lucked out and they were able to recode something in order to remove the triggers. Of course, since troubles always come in threes, this was no different. First the constraint problem, then the triggers, and then we hit the biggest roadblock that halted our Always Encrypted implementation.

Whamo

SELECT SUM(Salary) as TotalSalary from Table.

 TotalSalary from Table

Always encrypted does not currently support aggregations. Unfortunately, this is salary data and the code is full of aggregations. There was no way around it, and it was not feasible at this point to move the aggregations to the application side. Sadly, we had to abandon this solution and find another route. The good news is that this issue will be fixed in the next version of SQL Server. You can learn about secure enclave technology here.

In researching different possible roadblocks of Always Encrypted I came across a great blog post by Aaron Bertrand (B|T) where he lists several gotchas, if you are looking to implement Always Encrypted, I highly recommend starting by reading his post to discover what kind of issues you may run into.

Additionally, here is the official list directly from MSDN of what Is not supported.

Kapow

Always Encrypted is not supported for the columns with the below characteristics (for example, the Encrypted WITH clause cannot be used in CREATE TABLE/ALTER TABLE for a column, if any of the following conditions apply to the column)

  • Columns using one of the following datatypes, XML, timestamp/row version, image, text, text, sql_variant, hierarchy, geography, geometry, alias, and user types.
  • FILESTREAM columns
  • Columns with the IDENTITY property
  • Columns with ROWGUIDCOL property
  • String (varchar, char, etc.) columns with non-bin2 collations
  • Columns that are keys for nonclustered indices using a randomized encrypted column as a key column (deterministic encrypted columns are fine)
  • Columns that are keys for clustered indices using a randomized encrypted column as a key column (deterministic encrypted columns are fine)
  • Columns that are keys for full-text indices containing encrypted columns both randomized and deterministic
  • Columns referenced by computed columns (when the expression does unsupported operations for Always Encrypted)
  • Sparse column set
  • Columns that are referenced by statistics
  • Columns using alias type
  • Partitioning columns
  • Columns with default constraints
  • Columns referenced by unique constraints when using randomized encryption (deterministic encryption is supported)
  • Primary key columns when using randomized encryption (deterministic encryption is supported)
  • Referencing columns in foreign key constraints when using randomized encryption or when using deterministic encryption, if the referenced and referencing columns use different keys or algorithms
  • Columns referenced by check constraints
  • Columns in tables that use change data capture
  • Primary key columns on tables that have change tracking
  • Columns that are masked (using Dynamic Data Masking)
  • Columns in Stretch Database tables. (Tables with columns encrypted with Always Encrypted can be enabled for Stretch.)
  • Columns in external (PolyBase) tables (note: using external tables and tables with encrypted columns in the same query is supported)
  • Table-valued parameters targeting encrypted columns are not supported.

The following clauses cannot be used for encrypted columns.

  • FOR JSON PATH
  • FOR XML

Although I did take a few punches with this implementation I think Always Encrypted is a great choice to keep your data secure, and I will definitely use it in the future. I am looking forward to seeing how this option improves in the next versions of SQL Server.

Securing your environment is important no matter what option you implement. Learn more about database security. Register for the Denny Cherry and Associates webcast on Friday, January 19th, 2018 where we talk about Database Security including Spectre and Meltdown.


Similar Articles
Denny Cherry and Associates
Expert Consultants From HA to DR to up-time to SQL virtualization to scalability.