Using ADONET SqlClient library how to access the plain-text value of an encrypted column in SQL Server?
2
votes
0
answers
83
views
In a SQL Server 2017 database running on my development PC, a column in a particular table is encrypted with a column encryption key.
CREATE TABLE Test(
id int IDENTITY(1,1) NOT NULL PRIMARY KEY,
patientid int,
myencryptedcolumn varbinary(2000)
ENCRYPTED WITH (ENCRYPTION_TYPE = DETERMINISTIC,
ALGORITHM = 'AEAD_AES_256_CBC_HMAC_SHA_256',
COLUMN_ENCRYPTION_KEY = MYCEK) NOT NULL
)
In a stored procedure I'm able to decrypt the value using the column encryption key. But I'm also trying to test the ability of the ADO.NET SqlClient library to retrieve the plain-text value transparently and am not having any success there: the encrypted value is always returned to the client program.
Following this Microsoft documentation I've granted the following permissions to
[{My Dev PC Name}\{MyAccount}]
:
> **VIEW ANY COLUMN MASTER KEY DEFINITION**
> **VIEW ANY COLUMN ENCRYPTION KEY DEFINITION**
But that user has **VIEW ANY DEFINITION** already, as confirmed in SSMS Security->Logins-Properties->Securables.
And then, using the ADO.NET SqlClient library, I open a connection to the database using Integrated Security
when logged in to the dev PC as the account mentioned above and with Column Encryption Setting=enabled
tag in the connection string.
The SqlClient.SqlCommand object in the client app has these properties:
cmd.CommandText = "SELECT myencryptedcolumn FROM Test where id = 100";
cmd.CommandType = System.Data.CommandType.Text;
Multiple tuples are returned by the query and piped into a System.Data.DataTable:
var DA = new SqlDataAdapter();
var T = new System.Data.DataTable();
DA.SelectCommand = cmd;
DA.Fill(T);
string plaintext = BitConverter.ToString((byte[])T.Rows); -- get col value from 1st row
But variable plaintext
always contains a hex string representing the encrypted value not the plain-text value.
Unless I am misreading the Microsoft documentation, the ADO.NET client library should be able to decrypt myencryptededcolumn
client-side since the user executing the query (i.e. me, per the Integrated Security setting in the connection string) has the required permissions.
What am I overlooking? Am I supposed to be explicitly fetching the column encryption key and/or its definition and injecting that into some object in the ADO.NET client library? Is there another database permission involved?
Asked by Tim
(545 rep)
Dec 8, 2021, 04:31 PM