I am going to encrypted several fields in existing table. Basically, the following encryption technique is going to be used:
CREATE MASTER KEY ENCRYPTION
BY PASSWORD = 'sm_long_password@'
GO
CREATE CERTIFICATE CERT_01
WITH SUBJECT = 'CERT_01'
GO
CREATE SYMMETRIC KEY SK_01
WITH ALGORITHM = AES_256 ENCRYPTION
BY CERTIFICATE CERT_01
GO
OPEN SYMMETRIC KEY SK_01 DECRYPTION
BY CERTIFICATE CERT_01
SELECT ENCRYPTBYKEY(KEY_GUID('SK_01'), 'test')
CLOSE SYMMETRIC KEY SK_01
DROP SYMMETRIC KEY SK_01
DROP CERTIFICATE CERT_01
DROP MASTER KEY
The ENCRYPTBYKEY returns varbinary
with a maximum size of 8,000 bytes. Knowing the table fields going to be encrypted (for example: nvarchar(128)
, varchar(31)
, bigint
) how can I define the new varbinary
types length?
You can see the full specification here
So lets calculate:
16
byte key UID_4
bytes header16
byte IV (for AES, a 16 byte block cipher)Plus then the size of the encrypted message:
_4
byte magic number_2
bytes integrity bytes length_0
bytes integrity bytes (warning: may be wrongly placed in the table)_2
bytes (plaintext) message length_m
bytes (plaintext) message The CBC padding bytes should be calculated the following way:
16 - ((m + 4 + 2 + 2) % 16)
as padding is always applied. This will result in a number of padding bytes in the range 1..16. A sneaky shortcut is to just add 16 bytes to the total, but this may mean that you're specifying up to 15 bytes that are never used.
We can shorten this to 36 + 8 + m + 16 - ((m + 8) % 16)
or 60 + m - ((m + 8) % 16
. Or if you use the little trick specified above and you don't care about the wasted bytes: 76 + m
where m is the message input.
Notes: