Delen via


HANDTEKENING TOEVOEGEN (Transact-SQL)

van toepassing op:SQL ServerAzure SQL DatabaseAzure SQL Managed Instance

Hiermee voegt u een digitale handtekening toe aan een opgeslagen procedure, functie, assembly of DML-trigger. Voegt ook een tegenteken toe aan een opgeslagen procedure, functie, assembly of DML-trigger.

Transact-SQL syntaxisconventies

Syntaxis

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

Argumenten

module_class

De klasse van de module waaraan de handtekening wordt toegevoegd. De standaardinstelling voor modules met schemabereik is OBJECT.

module_name

De naam van een opgeslagen procedure, functie, assembly of trigger die moet worden ondertekend of ondertekend.

CERTIFICAAT cert_name

De naam van een certificaat waarmee de opgeslagen procedure, functie, assembly of trigger moet worden ondertekend of ondertekend.

WITH PASSWORD = 'password'

Het wachtwoord dat is vereist voor het ontsleutelen van de persoonlijke sleutel van het certificaat of asymmetrische sleutel. Deze component is alleen vereist als de persoonlijke sleutel niet wordt beveiligd door de hoofdsleutel van de database.

SIGNATURE = signed_blob

Hiermee geeft u het ondertekende, binaire grote object (BLOB) van de module. Deze component is handig als u een module wilt verzenden zonder de persoonlijke sleutel te verzenden. Wanneer u deze component gebruikt, zijn alleen de module, handtekening en openbare sleutel vereist om het ondertekende binaire grote object toe te voegen aan een database. signed_blob is de blob zelf in hexadecimale indeling.

ASYMMETRISCHE SLEUTEL Asym_Key_Name

De naam van een asymmetrische sleutel waarmee de opgeslagen procedure, functie, assembly of trigger moet worden ondertekend of ondertekend.

Opmerkingen

De module die wordt ondertekend of ondertekend en het certificaat of de asymmetrische sleutel die wordt gebruikt om deze te ondertekenen, moet al bestaan. Elk teken in de module wordt opgenomen in de handtekeningberekening. Dit omvat geleide regelterugloop en lijnfeeds.

Een module kan worden ondertekend en ondertekend door een willekeurig aantal certificaten en asymmetrische sleutels.

De handtekening van een module wordt verwijderd wanneer de module wordt gewijzigd.

Als een module een EXECUTE AS component bevat, wordt de beveiligings-id (SID) van de principal ook opgenomen als onderdeel van het ondertekeningsproces.

Voorzichtigheid

Moduleondertekening mag alleen worden gebruikt om machtigingen te verlenen, nooit machtigingen te weigeren of in te trekken.

DDL-triggers (Data Definition Language) en inline-tabelwaardefuncties kunnen niet worden ondertekend.

Informatie over handtekeningen is zichtbaar in de catalogusweergave sys.crypt_properties.

Waarschuwing

Wanneer u een procedure voor handtekening opnieuw maakt, moeten alle instructies in de oorspronkelijke batch overeenkomen met de opnieuw gemaakte batch. Als een deel van de batch verschilt, zelfs in spaties of opmerkingen, is de resulterende handtekening anders.

Tegentekens

Wanneer u een ondertekende module uitvoert, worden de handtekeningen tijdelijk toegevoegd aan het SQL-token, maar gaan de handtekeningen verloren als de module een andere module uitvoert of als de module de uitvoering beëindigt. Een tegentekening is een speciale vorm van handtekening. Op zichzelf verleent een tegenteken geen machtigingen. Er kunnen echter handtekeningen van hetzelfde certificaat of asymmetrische sleutel worden bewaard voor de duur van de aanroep naar het object dat is opgegeven.

Stel bijvoorbeeld dat de gebruiker procedure Alice aanroept ProcForAlice, die procedure ProcSelectT1aanroept, die uit de tabel T1selecteert. Alice heeft EXECUTE machtiging voor ProcForAlice, maar heeft geen EXECUTE machtigingen voor ProcSelectT1 of SELECT machtiging voor T1, en er is geen eigendomsketen betrokken bij deze hele keten. Alice heeft geen toegang tot tabel T1, hetzij rechtstreeks of met behulp van ProcForAlice en ProcSelectT1. Omdat we willen dat Alice altijd ProcForAlice gebruikt voor toegang, willen we haar geen toestemming geven om ProcSelectT1uit te voeren. Hoe kunnen we dit scenario uitvoeren?

  • Als we ProcSelectT1ondertekenen, zodat ProcSelectT1 toegang heeft tot T1, kan Alice ProcSelectT1 rechtstreeks aanroepen en hoeft ze niet ProcForAliceaan te roepen.

  • We kunnen EXECUTE machtiging voor ProcSelectT1 aan Alice weigeren, maar Alice kan ProcSelectT1 niet aanroepen via ProcForAlice.

  • Ondertekening ProcForAlice zou niet op zichzelf werken, omdat de handtekening verloren gaat in de aanroep van ProcSelectT1.

Als u echter ProcSelectT1 met hetzelfde certificaat gebruikt om ProcForAlicete ondertekenen, wordt de handtekening bewaard in de oproepketen en is toegang tot T1toegestaan. Als Alice ProcSelectT1 rechtstreeks probeert aan te roepen, heeft ze geen toegang tot T1, omdat de aantekening geen rechten verleent. voorbeeld van C wordt de Transact-SQL voor dit voorbeeld weergegeven.

Schermafbeelding van handtekeningvoorbeeld.

Machtigingen

Vereist ALTER machtiging voor het object en CONTROL machtiging voor het certificaat of de asymmetrische sleutel. Als een bijbehorende persoonlijke sleutel wordt beveiligd met een wachtwoord, moet de gebruiker ook het wachtwoord hebben.

Voorbeelden

Een. Een opgeslagen procedure ondertekenen met behulp van een certificaat

In het volgende voorbeeld wordt de opgeslagen procedure HumanResources.uspUpdateEmployeeLogin ondertekend met het certificaat HumanResourcesDP.

USE AdventureWorks2022;

ADD SIGNATURE TO HumanResources.uspUpdateEmployeeLogin
    BY CERTIFICATE HumanResourcesDP;
GO

B. Een opgeslagen procedure ondertekenen met behulp van een ondertekende BLOB

In het volgende voorbeeld wordt een nieuwe database gemaakt en wordt een certificaat gemaakt dat in het voorbeeld moet worden gebruikt. In het voorbeeld wordt een eenvoudige opgeslagen procedure gemaakt en ondertekend en wordt de handtekening-BLOB opgehaald uit sys.crypt_properties. De handtekening wordt vervolgens verwijderd en opnieuw toegevoegd. In het voorbeeld wordt de procedure ondertekend met behulp van de WITH SIGNATURE syntaxis.

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

De crypt_property handtekening die door deze instructie wordt geretourneerd, verschilt telkens wanneer u een procedure maakt. Noteer het resultaat voor gebruik verderop in dit voorbeeld. In dit specifieke geval wordt het resultaat 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. Een procedure openen met behulp van een aantekening

In het volgende voorbeeld ziet u hoe met contrasigning de toegang tot een object kan worden bepaald. U moet <password> vervangen door een geschikt wachtwoord.

-- 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;