SQL Server ile Veri Şifreleme (Data Encryption)

Cihan Ozhan
3 min readJun 16, 2023

--

2014 yılında yayınladığım bir makalemi cihanozhan.com arşivinden medium’a aktarıyorum.

Bilgi teknolojilerinde verinin güvenliği çok kritik bir öneme sahiptir. Önemli verileri korumak için ekstra bir çok yazılım geliştirildiği gibi bu alana özel olarak çalışan bir çok güvenlik firması mevcuttur. Veri güvenliği dediğimde bir veritabanı programcısının ilk aklına gelen sanıyorum bankacılık ve finans sektörüdür. Tabi ki en yüksek güvenliğe ihtiyacı olan sektör bankacılıktır. Ancak sizin korumanız gereken bilgiler de olacaktır. Bu nedenle veritabanında tuttuğunuz verinin güvenliğini sağlamak önemlidir.

Basit bir örnek vermek gerekirse;

SELECT HASHBYTES('SHA1','www.cihanozhan.com');

Bu basit örnekte SHA1 yerine MD2, MD4, MD5, SHA, SHA1 anahtar kelimeleri de kullanılabilir.

Yukarıdaki örnekte basit bir çalışma yapmış olsa da veritabanı nesnel yapısında işler daha karmaşık ve komplekstir. Genel olarak Transaction anlatımlarını bir BankingDB içerisinde Accounts isimli tablo oluşturarak anlatırım. Bu makalede de aynı yolu izleyerek Accounts tablosu üzerinde anlatacağım. Bir bankamız var ve müşterilerin bilgilerini korumak istiyoruz.

Standart hazırlığımızı yaparak sorgu ekranının master veritabanını kullanmasını garanti edelim.

USE master
GO

BankingDB isimli veritabanımızı oluşturalım.

CREATE DATABASE BankingDB

Sorgularımızın BankingDB üzerinde çalışması için;

USE BankingDB
GO

Veritabanı üzerinde bir Login oluşturalım.

CREATE LOGIN BankingDBLogin WITH Password = '2+5&/@fF^#%i-';
GO

Ve bu login ile çalışacak yeni bir kullanıcı oluşturalım.

CREATE USER BankingDBUser FOR LOGIN BankingDBLogin;

Şimdi de, BankingDB veritabanında Accounts adında müşteri hesap bilgilerini tutan bir tablo oluşturalım.

CREATE TABLE Accounts
(
AccountID INT,
FName NVARCHAR(25),
LName NVARCHAR(25),
CreditCardType VARBINARY(1000),
CreditCardNumber VARBINARY(1000),
AccountNotes VARBINARY(MAX)
);
GO

Veritabanı, tablo ve kullanıcı işlemlerinin son halkası ise kullanıcımıza Accounts tablosu üzerinde SELECT ve INSERT yetkisi vermektir.

GRANT SELECT, INSERT ON Accounts TO BankingDBUser;

Bu işlemlerden sonra şifreleme işlemlerine geçebiliriz. Öncelikle veritabanı için bir Master Key oluşturuyoruz.

CREATE MASTER KEY ENCRYPTION BY PASSWORD = 'kO0_3^^#$25KFQAUIXZ';

Kullanıcımız için bir AsymmetricKey oluşturuyoruz.

CREATE ASYMMETRIC KEY BankingDBUserAsymmetricKey AUTHORIZATION BankingDBUser 
WITH ALGORITHM = RSA_2048 ENCRYPTION BY PASSWORD = 'dF_4%&+-X-AKLZHN*';

Kullanıcımız için bir SymmetricKey oluşturuyoruz.

CREATE SYMMETRIC KEY BankingDBUserSymmetricKey WITH ALGORITHM = AES_256 
ENCRYPTION BY ASYMMETRIC KEY BankingDBUserAsymmetricKey;

Key oluşturma işlemlerimiz tamamlandı. Şimdi veri ekleme işlemi yaparak şifreli veriyi nasıl ekleyeceğimize bakalım. Öncelikle SQL Server’a yeni eklenen bir özellik olan Sequence’imizi oluşturalım.

CREATE SEQUENCE [dbo].[AccountSeq] AS INT
START WITH 1
INCREMENT BY 1
GO

Not : Oracle veritabanı programcıları için Sequence tanıdık gelse de, SQL Server geliştiricileri için yeni bir kavramdır. Özetle, daha önce bir tabloda Identity Column olarak belirterek otomatik artan bir sütun oluşturduğumuz durumlarda, artık Sequence oluşturarak otomatik artan alanları kendimizin INSERT işlemi sırasında yönetebilmemizi sağlayan bir özelliktir. Bilgi için Oracle videolarımdan Sequence videosunu izleyebilirsiniz.

Artık veri ekleyebiliriz.

OPEN SYMMETRIC KEY BankingDBUserSymmetricKey DECRYPTION BY ASYMMETRIC KEY BankingDBUserAsymmetricKey WITH PASSWORD = 'dF_4%&+-X-AKLZHN*'
INSERT INTO Accounts VALUES(NEXT VALUE FOR dbo.AccountSeq, 'Cihan','Özhan',
EncryptByKey(Key_GUID('BankingDBUserSymmetricKey'),'MasterCard'),
EncryptByKey(Key_GUID('BankingDBUserSymmetricKey'),'9823-2343-1122-3214'),
EncryptByKey(Key_GUID('BankingDBUserSymmetricKey'),'Bu hesap sahibi baya zengin.'));
CLOSE SYMMETRIC KEY BankingDBUserSymmetricKey

Sıradan INSERT işleminden biraz farklı görünüyor değil mi? Bu veri ekleme yöntemi Key kullanımları için gereklidir. INSERT işleminden önce Symmetric Key’imizi OPEN ile açarak INSERT işlemini yapıp daha sonra CLOSE ile Symmetric Key’i kapatıyoruz.

Yukarıdaki işlemleri hatasız şekilde tamamladıysanız aşağıdaki gibi bir görüntüyle karşılaşmanız gerekir.

SELECT * FROM Accounts;

Görüldüğü üzere veri ekleme işlemi başarıyla gerçekleşti. Tabi veriyi şifreleyerek koruduk ancak biz bu veriye nasıl ulaşacağız? Bu sorunun cevabı da gene SELECT sorgusu ancak biraz farklı… Şöyleki;

OPEN SYMMETRIC KEY BankingDBUserSymmetricKey DECRYPTION BY ASYMMETRIC KEY BankingDBUserAsymmetricKey WITH PASSWORD = 'dF_4%&+-X-AKLZHN*'
SELECT
AccountID, FName, LName,
CONVERT(VARCHAR, DecryptByKey(CreditCardType)) AS CreditCardType,
CONVERT(VARCHAR, DecryptByKey(CreditCardNumber)) AS CreditCardNumber,
CONVERT(VARCHAR, DecryptByKey(AccountNotes)) AS AccountNotes
FROM Accounts
CLOSE SYMMETRIC KEY BankingDBUserSymmetricKey

Veriyi şifreli bir şekilde sakladığımız için okuma işleminde de gene Key’leri kullanmalıyız. Bu sorgu sonucu aşağıdaki gibi olacaktır.

Key’ler ile ilgili bilgi almak için aşağıdaki sorguları kullanabilirsiniz.

SELECT * FROM sys.certificates
SELECT * FROM sys.asymmetric_keys
SELECT * FROM sys.database_principals
SELECT * FROM sys.key_encryptions
SELECT * FROM sys.crypt_properties
SELECT * FROM sys.key_encryptions

Cihan Özhan

--

--