ADD SIGNATURE (Transact-SQL)
platí pro:SQL Server
Azure SQL Database
azure SQL Managed Instance
Přidá digitální podpis do uložené procedury, funkce, sestavení nebo triggeru DML. Přidá také countersignature do uložené procedury, funkce, sestavení nebo triggerU DML.
Syntax
ADD [ COUNTER ] SIGNATURE TO module_class::module_name
BY <crypto_list> [ , ...n ]
<crypto_list> ::=
CERTIFICATE cert_name
| CERTIFICATE cert_name [ WITH PASSWORD = 'password' ]
| CERTIFICATE cert_name WITH SIGNATURE = signed_blob
| ASYMMETRIC KEY Asym_Key_Name
| ASYMMETRIC KEY Asym_Key_Name [ WITH PASSWORD = 'password' ]
| ASYMMETRIC KEY Asym_Key_Name WITH SIGNATURE = signed_blob
Argumenty
module_class
Třída modulu, do kterého se podpis přidá. Výchozí hodnota pro moduly s oborem schématu je OBJECT
.
module_name
Název uložené procedury, funkce, sestavení nebo triggeru, který se má podepsat nebo podepsaný.
CERT_NAME CERTIFIKÁTU
Název certifikátu, pomocí kterého se má podepsat uložená procedura, funkce, sestavení nebo aktivační událost nebo podepisovat.
WITH PASSWORD = 'password'
Heslo, které je nutné k dešifrování privátního klíče certifikátu nebo asymetrického klíče. Tato klauzule se vyžaduje jenom v případě, že privátní klíč není chráněný hlavním klíčem databáze.
SIGNATURE = signed_blob
Určuje podepsaný binární rozsáhlý objekt (BLOB) modulu. Tato klauzule je užitečná, pokud chcete dodat modul bez odeslání privátního klíče. Při použití této klauzule se k přidání binárního velkého objektu podepsaného do databáze vyžaduje pouze modul, podpis a veřejný klíč. signed_blob je samotný objekt blob v šestnáctkovém formátu.
ASYMETRICKÝ KLÍČ Asym_Key_Name
Název asymetrického klíče, pomocí kterého chcete podepsat uloženou proceduru, funkci, sestavení nebo trigger nebo podepisovat znaménko čítače.
Poznámky
Modul podepsaný nebo podepsaný a certifikát nebo asymetrický klíč použitý k podepsání musí již existovat. Každý znak v modulu je součástí výpočtu podpisu. To zahrnuje návraty na začátek řádku a odřádkování.
Modul lze podepsat a řadit libovolným počtem certifikátů a asymetrických klíčů.
Podpis modulu se při změně modulu zahodí.
Pokud modul obsahuje klauzuli EXECUTE AS
, id zabezpečení (SID) objektu zabezpečení je také součástí procesu podepisování.
Opatrnost
Podepisování modulů by se mělo používat jenom k udělení oprávnění, nikdy k odepření nebo odvolání oprávnění.
Triggery jazyka DDL (Data Definition Language) a vložené funkce s hodnotami tabulky nelze podepsat.
Informace o podpisech jsou viditelné v zobrazení katalogu sys.crypt_properties
.
Varování
Při opětovném vytvoření procedury pro podpis se všechny příkazy v původní dávce musí shodovat s znovu vytvořenou dávkou. Pokud se některá část dávky liší, a to i v mezerách nebo komentářích, výsledný podpis se liší.
Čítače
Když spustíte podepsaný modul, podpisy se dočasně přidají do tokenu SQL, ale podpisy se ztratí, pokud modul spustí jiný modul nebo pokud modul ukončí provádění. countersignature je speciální forma podpisu. Sám o sobě countersignature neuděluje žádná oprávnění. Umožňuje však uchovávat podpisy vytvořené stejným certifikátem nebo asymetrickým klíčem po dobu trvání volání objektu s znaménkami.
Předpokládejme například, že uživatel Alice
volá proceduru ProcForAlice
, která volá proceduru ProcSelectT1
, která vybere z tabulky T1
. Alice má EXECUTE
oprávnění k ProcForAlice
, ale nemá oprávnění EXECUTE
k ProcSelectT1
nebo SELECT
oprávnění k T1
a v celém řetězci se nezabíná řetězení vlastnictví. Alice nemá přístup k tabulce T1
, buď přímo, nebo pomocí ProcForAlice
a ProcSelectT1
. Vzhledem k tomu, že chceme, aby Alice vždy používala ProcForAlice
pro přístup, nechceme jí udělit oprávnění ke spuštění ProcSelectT1
. Jak můžeme tento scénář dosáhnout?
Pokud podepíšeme
ProcSelectT1
, abyProcSelectT1
měl přístup kT1
, Alice může vyvolatProcSelectT1
přímo a nemusí volatProcForAlice
.Mohli bychom
EXECUTE
povoleníProcSelectT1
Alice, ale Alice nemůže volatProcSelectT1
prostřednictvímProcForAlice
.Podepisování
ProcForAlice
by samo o sobě nefungovalo, protože podpis se ztratí ve voláníProcSelectT1
.
Pokud však podepíšete ProcSelectT1
se stejným certifikátem, který se používá k podepisování ProcForAlice
, podpis se uchovává v rámci řetězu volání a má povolený přístup k T1
. Pokud se Alice pokusí zavolat ProcSelectT1
přímo, nemůže získat přístup k T1
, protože countersignature neuděluje žádná práva.
příklad C ukazuje Transact-SQL pro tento příklad.
Dovolení
Vyžaduje ALTER
oprávnění k objektu a CONTROL
oprávnění k certifikátu nebo asymetrického klíče. Pokud je přidružený privátní klíč chráněný heslem, musí mít uživatel také heslo.
Příklady
A. Podepsání uložené procedury pomocí certifikátu
Následující příklad podepíše uloženou proceduru HumanResources.uspUpdateEmployeeLogin
certifikátem HumanResourcesDP
.
USE AdventureWorks2022;
ADD SIGNATURE TO HumanResources.uspUpdateEmployeeLogin
BY CERTIFICATE HumanResourcesDP;
GO
B. Podepsání uložené procedury pomocí podepsaného objektu BLOB
Následující příklad vytvoří novou databázi a vytvoří certifikát, který se použije v příkladu. Příklad vytvoří a podepíše základní uloženou proceduru a načte objekt BLOB podpisu z sys.crypt_properties
. Podpis se pak zahodí a znovu přidá. Příklad podepíše proceduru pomocí syntaxe WITH SIGNATURE
.
CREATE DATABASE TestSignature;
GO
USE TestSignature;
GO
-- Create a CERTIFICATE to sign the procedure.
CREATE CERTIFICATE cert_signature_demo
ENCRYPTION BY PASSWORD = 'pGFD4bb925DGvbd2439587y'
WITH SUBJECT = 'ADD SIGNATURE demo';
GO
-- Create a basic procedure.
CREATE PROCEDURE [sp_signature_demo]
AS
PRINT 'This is the content of the procedure.';
GO
-- Sign the procedure.
ADD SIGNATURE TO [sp_signature_demo]
BY CERTIFICATE [cert_signature_demo] WITH PASSWORD = 'pGFD4bb925DGvbd2439587y';
GO
-- Get the signature binary BLOB for the sp_signature_demo procedure.
SELECT cp.crypt_property
FROM sys.crypt_properties AS cp
INNER JOIN sys.certificates AS cer
ON cp.thumbprint = cer.thumbprint
WHERE cer.name = 'cert_signature_demo';
GO
Podpis crypt_property
vrácený tímto příkazem se při každém vytvoření procedury liší. Poznamenejte si výsledek pro pozdější použití v tomto příkladu. V tomto konkrétním případě je výsledek ukázaný 0x831F5530C86CC8ED606E5BC2720DA835351E46219A6D5DE9CE546297B88AEF3B6A7051891AF3EE7A68EAB37CD8380988B4C3F7469C8EABDD9579A2A5C507A4482905C2F24024FFB2F9BD7A953DD5E98470C4AA90CE83237739BB5FAE7BAC796E7710BDE291B03C43582F6F2D3B381F2102EEF8407731E01A51E24D808D54B373
.
-- Drop the signature so that it can be signed again.
DROP SIGNATURE FROM [sp_signature_demo]
BY CERTIFICATE [cert_signature_demo];
GO
-- Add the signature. Use the signature BLOB obtained earlier.
ADD SIGNATURE TO [sp_signature_demo]
BY CERTIFICATE [cert_signature_demo] WITH SIGNATURE = 0x831F5530C86CC8ED606E5BC2720DA835351E46219A6D5DE9CE546297B88AEF3B6A7051891AF3EE7A68EAB37CD8380988B4C3F7469C8EABDD9579A2A5C507A4482905C2F24024FFB2F9BD7A953DD5E98470C4AA90CE83237739BB5FAE7BAC796E7710BDE291B03C43582F6F2D3B381F2102EEF8407731E01A51E24D808D54B373;
GO
C. Přístup k postupu pomocí čítače
Následující příklad ukazuje, jak může countersigning pomoct řídit přístup k objektu. Je nutné nahradit <password>
odpovídajícím heslem.
-- Create tesT1 database
CREATE DATABASE testDB;
GO
USE testDB;
GO
-- Create table T1
CREATE TABLE T1 (c VARCHAR (11));
INSERT INTO T1 VALUES ('This is T1.');
-- Create a TestUser user to own table T1
CREATE USER TestUser WITHOUT LOGIN;
ALTER AUTHORIZATION ON T1 TO TestUser;
-- Create a certificate for signing
CREATE CERTIFICATE csSelectT
ENCRYPTION BY PASSWORD = '<password>'
WITH SUBJECT = 'Certificate used to grant SELECT on T1';
CREATE USER ucsSelectT1 FOR CERTIFICATE csSelectT;
GRANT SELECT ON T1 TO ucsSelectT1;
-- Create a principal with low privileges
CREATE LOGIN Alice WITH PASSWORD = '<password>';
CREATE USER Alice;
-- Verify Alice cannoT1 access T1;
EXECUTE AS LOGIN = 'Alice';
SELECT * FROM T1;
REVERT;
GO
-- Create a procedure that directly accesses T1
CREATE PROCEDURE procSelectT1
AS
BEGIN
PRINT 'Now selecting from T1...';
SELECT *
FROM T1;
END
GO
GRANT EXECUTE ON ProcSelectT1 TO PUBLIC;
GO
-- Create special procedure for accessing T1
CREATE PROCEDURE ProcForAlice
AS
BEGIN
IF USER_ID() <> USER_ID('Alice')
BEGIN
PRINT 'Only Alice can use this.';
RETURN;
END
EXECUTE ProcSelectT1;
END
GO
GRANT EXECUTE ON ProcForAlice TO PUBLIC;
-- Verify procedure works for a sysadmin user
EXECUTE ProcForAlice;
-- Alice still can't use the procedure yet
EXECUTE AS LOGIN = 'Alice';
EXECUTE ProcForAlice;
REVERT;
-- Sign procedure to grant it SELECT permission
ADD SIGNATURE TO ProcForAlice
BY CERTIFICATE csSelectT WITH PASSWORD = '<password>';
ADD COUNTER SIGNATURE TO ProcSelectT1
BY CERTIFICATE csSelectT WITH PASSWORD = '<password>';
-- Now the stored procedure works.
-- Note that calling ProcSelectT1 directly still doesn't work.
EXECUTE AS LOGIN = 'Alice';
EXECUTE ProcForAlice;
EXECUTE ProcSelectT1;
REVERT;
-- Cleanup
USE master;
GO
DROP DATABASE testDB;
DROP LOGIN Alice;