Preskočiť na obsah
Skript

Certifikáty a TDE – expirácia a zálohy kľúčov

Všetky certifikáty v master aj v používateľských databázach s dátumom expirácie a poslednej zálohy privátneho kľúča, plus stav TDE šifrovania a ktorým certifikátom je chránené.

certifikaty-a-tde-expiracia-a-zalohy-klucov.sql 83 riadkov · T-SQL
Parametre skriptu doplň a kopíruj hotový skript
/* DeadlockCafe | Certifikáty a TDE – expirácia a zálohy kľúčov
   Účel:  Všetky certifikáty v master aj v používateľských databázach s dátumom expirácie a poslednej zálohy privátneho kľúča, plus stav TDE šifrovania a ktorým certifikátom je chránené.
   Režim: READ ONLY | SQL Server 2016 – 2022, on-premises
*/
SET NOCOUNT ON;

DECLARE @WarnDays int = {{WarnDays:90|Upozorniť koľko dní pred expiráciou}};

IF OBJECT_ID(N'tempdb..#cert') IS NOT NULL DROP TABLE #cert;
CREATE TABLE #cert
(
    database_name            sysname        NOT NULL,
    certificate_name         sysname        NOT NULL,
    subject                  nvarchar(4000) NULL,
    start_date               datetime       NULL,
    expiry_date              datetime       NULL,
    pvt_key_encryption       nvarchar(60)   NULL,
    pvt_key_last_backup_date datetime       NULL,
    thumbprint               varbinary(32)  NULL
);

DECLARE @db sysname, @sql nvarchar(max);
DECLARE dbs CURSOR LOCAL FAST_FORWARD FOR
    SELECT name FROM sys.databases
    WHERE state = 0 AND HAS_DBACCESS(name) = 1 AND name NOT IN (N'tempdb', N'model')
    ORDER BY CASE WHEN name = N'master' THEN 0 ELSE 1 END, name;
OPEN dbs;
FETCH NEXT FROM dbs INTO @db;
WHILE @@FETCH_STATUS = 0
BEGIN
    SET @sql = N'USE ' + QUOTENAME(@db) + N';
INSERT INTO #cert (database_name, certificate_name, subject, start_date, expiry_date,
                   pvt_key_encryption, pvt_key_last_backup_date, thumbprint)
SELECT DB_NAME(), c.name, c.subject, c.start_date, c.expiry_date,
       c.pvt_key_encryption_type_desc, c.pvt_key_last_backup_date, c.thumbprint
FROM sys.certificates AS c
WHERE c.name NOT LIKE N''##%'';';
    BEGIN TRY
        EXEC sys.sp_executesql @sql;
    END TRY
    BEGIN CATCH
        PRINT N'Preskočená databáza ' + @db + N': ' + ERROR_MESSAGE();
    END CATCH;
    FETCH NEXT FROM dbs INTO @db;
END;
CLOSE dbs;
DEALLOCATE dbs;

-- 1) certifikáty
SELECT c.database_name, c.certificate_name, c.subject, c.start_date, c.expiry_date,
       DATEDIFF(DAY, GETDATE(), c.expiry_date) AS days_to_expiry,
       CASE WHEN c.expiry_date < GETDATE() THEN N'EXPIROVANÝ'
            WHEN c.expiry_date < DATEADD(DAY, @WarnDays, GETDATE()) THEN N'EXPIRUJE ČOSKORO'
            ELSE N'OK' END AS expiry_status,
       c.pvt_key_encryption,
       c.pvt_key_last_backup_date,
       CASE WHEN c.database_name = N'master'
             AND EXISTS (SELECT 1 FROM sys.dm_database_encryption_keys AS k WHERE k.encryptor_thumbprint = c.thumbprint)
            THEN 1 ELSE 0 END AS is_tde_protector
FROM #cert AS c
ORDER BY is_tde_protector DESC, c.expiry_date;

-- 2) TDE databázy (encryption_state_desc je až od 2019, preto CASE)
SELECT DB_NAME(k.database_id) AS database_name,
       CASE k.encryption_state
            WHEN 0 THEN N'bez DEK' WHEN 1 THEN N'nešifrovaná' WHEN 2 THEN N'šifruje sa'
            WHEN 3 THEN N'šifrovaná' WHEN 4 THEN N'mení sa kľúč' WHEN 5 THEN N'dešifruje sa'
            WHEN 6 THEN N'mení sa ochrana DEK' END AS encryption_state,
       k.percent_complete,
       k.key_algorithm, k.key_length, k.encryptor_type,
       c.certificate_name                 AS encryptor_certificate,
       c.expiry_date                      AS certificate_expiry,
       c.pvt_key_last_backup_date,
       CASE WHEN k.database_id = 2 THEN N'tempdb – šifrovaná automaticky'
            WHEN k.encryptor_type = N'CERTIFICATE' AND c.certificate_name IS NULL THEN N'certifikát v master nenájdený (chýbajú práva?)'
            WHEN k.encryptor_type = N'CERTIFICATE' AND c.pvt_key_last_backup_date IS NULL
                 THEN N'RIZIKO: kľúč certifikátu nebol zálohovaný – zálohu DB neobnovíš na inom serveri'
            WHEN k.encryptor_type = N'CERTIFICATE' THEN N'OK'
            ELSE N'iný encryptor (asymetrický kľúč / EKM) – over ručne' END AS key_backup_status
FROM sys.dm_database_encryption_keys AS k
LEFT JOIN #cert AS c ON c.database_name = N'master' AND c.thumbprint = k.encryptor_thumbprint
ORDER BY database_name;
## Kedy použiť

Pred migráciou alebo obnovou TDE databázy na iný server, pri audite šifrovania, alebo keď sa blíži expirácia certifikátov (Service Broker, podpisovanie modulov, Always On endpointy).

## Ako čítať výsledok

Prvá sada: certifikáty – `days_to_expiry`, `expiry_status` a `pvt_key_last_backup_date`. `is_tde_protector = 1` označuje certifikát v master, ktorým je chránený DEK niektorej databázy. Druhá sada: TDE databázy – stav šifrovania, percento pri prebiehajúcom šifrovaní a `key_backup_status`. **NULL v `pvt_key_last_backup_date` pri TDE certifikáte je kritické** – záloha databázy sa bez neho na inom serveri nedá obnoviť.

> [!WARNING]
> Pre TDE sa expirácia certifikátu **nevynucuje** – expirovaný certifikát databázu ďalej šifruje a dešifruje, ale audit ho môže vytknúť. `pvt_key_last_backup_date` vie len o zálohe cez `BACKUP CERTIFICATE`, nie o tom, kde súbor leží a či máš heslo. `tempdb` sa zobrazí ako šifrovaná, ak má TDE ktorákoľvek databáza – to je normálne. Databázy, do ktorých sa nedá prihlásiť, sa preskočia.

**Oprávnenia:** Prístup do databáz (pre ich `sys.certificates`). TDE DMV: `VIEW SERVER STATE` (2016–2019), na SQL Server 2022 `VIEW SERVER SECURITY STATE`.  
**Režim:** READ ONLY · **Verzia:** SQL Server 2016 – 2022

## Súvisiace recepty

- [Bezpečnostný baseline inštancie](script.php?id=53&s=bezpecnostny-baseline-instancie)
- [Migrácia databázy na nový server – checklist](script.php?id=62&s=migracia-databazy-na-novy-server-checklist)
- [Obnova databázy k bodu v čase](script.php?id=60&s=obnova-databazy-k-bodu-v-case-point-in-time-restore)

## Zdroje

- [sys.certificates](https://learn.microsoft.com/en-us/sql/relational-databases/system-catalog-views/sys-certificates-transact-sql)
- [sys.dm_database_encryption_keys](https://learn.microsoft.com/en-us/sql/relational-databases/system-dynamic-management-views/sys-dm-database-encryption-keys-transact-sql)
- [Transparent data encryption (TDE)](https://learn.microsoft.com/en-us/sql/relational-databases/security/encryption/transparent-data-encryption)

_Skript je staticky overený proti dokumentácii Microsoft Learn (názvy DMV, stĺpcov a hodnôt), nie spustený na živom serveri. Pred použitím na PROD ho vyskúšaj na TEST._