Sdílet prostřednictvím


ADD SIGNATURE (Transact-SQL)

platí pro:SQL ServerAzure SQL Databaseazure 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.

Transact-SQL konvence syntaxe

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 T1a 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, aby ProcSelectT1 měl přístup k T1, Alice může vyvolat ProcSelectT1 přímo a nemusí volat ProcForAlice.

  • Mohli bychom EXECUTE povolení ProcSelectT1 Alice, ale Alice nemůže volat ProcSelectT1 prostřednictvím ProcForAlice.

  • 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.

snímek obrazovky s příkladem podpisu

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;
  • sys.crypt_properties (Transact-SQL)
  • DROP SIGNATURE (Transact-SQL)