Udostępnij za pomocą


DODAJ PODPIS (Transact-SQL)

Dotyczy:SQL ServerAzure SQL DatabaseAzure SQL Managed InstanceBaza danych SQL w usłudze Microsoft Fabric

Dodaje podpis cyfrowy do procedury składowanej, funkcji, zestawu lub wyzwalacza DML. Dodaje również kontrapis do procedury składowanej, funkcji, zestawu lub wyzwalacza DML.

Transact-SQL konwencje składni

Składnia

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

Klasa modułu, do którego jest dodawany podpis. Domyślnym ustawieniem modułów o zakresie schematu jest OBJECT.

module_name

Nazwa procedury składowanej, funkcji, zestawu lub wyzwalacza, która ma być podpisana lub podpisana.

cert_name CERTYFIKATU

Nazwa certyfikatu, za pomocą którego można podpisać lub przypisać procedurę składowaną, funkcję, zestaw lub wyzwalacz.

Z HASŁEM = 'hasło'

Hasło wymagane do odszyfrowania klucza prywatnego certyfikatu lub klucza asymetrycznego. Ta klauzula jest wymagana tylko wtedy, gdy klucz prywatny nie jest chroniony przez klucz główny bazy danych.

PODPIS = signed_blob

Określa podpisany, binarny duży obiekt (BLOB) modułu. Ta klauzula jest przydatna, jeśli chcesz wysłać moduł bez wysyłania klucza prywatnego. W przypadku użycia tej klauzuli do bazy danych wymagany jest tylko moduł, podpis i klucz publiczny, aby dodać podpisany duży obiekt binarny do bazy danych. signed_blob jest sam obiekt blob w formacie szesnastkowym.

ASYM_KEY_NAME KLUCZA ASYMETRYCZNEGO

Nazwa klucza asymetrycznego, za pomocą którego można podpisać lub podpisać licznik procedury składowanej, funkcji, zestawu lub wyzwalacza.

Uwagi

Podpisany lub podpisany moduł oraz certyfikat lub klucz asymetryczny użyty do podpisania go musi już istnieć. Każdy znak w module jest uwzględniony w obliczeniu podpisu. Obejmuje to wiodące powroty karetki i źródła linii.

Moduł może być podpisany i podpisany przez dowolną liczbę certyfikatów i kluczy asymetrycznych.

Podpis modułu jest odrzucany po zmianie modułu.

Jeśli moduł zawiera klauzulę EXECUTE AS, identyfikator zabezpieczeń (SID) podmiotu zabezpieczeń jest również uwzględniony w ramach procesu podpisywania.

Ostrożność

Podpisywanie modułu powinno być używane tylko do udzielania uprawnień, nigdy nie odmawiaj ani odwoływanie uprawnień.

Wyzwalacze języka definicji danych (DDL) i wbudowane funkcje tabel nie mogą być podpisane.

Informacje o sygnaturach są widoczne w widoku katalogu sys.crypt_properties.

Ostrzeżenie

Po ponownym utworzeniu procedury podpisu wszystkie instrukcje w oryginalnej partii muszą być zgodne z ponownie utworzoną partią. Jeśli jakakolwiek część partii różni się, nawet w spacjach lub komentarzach, wynikowy podpis jest inny.

Kontrasygnatur

Po wykonaniu podpisanego modułu podpisy są tymczasowo dodawane do tokenu SQL, ale podpisy zostaną utracone, jeśli moduł wykonuje inny moduł lub jeśli moduł zakończy wykonywanie. countersignature jest specjalną formą podpisu. Samozwańcze przypisanie nie przyznaje żadnych uprawnień. Umożliwia jednak zachowywanie podpisów przez ten sam certyfikat lub klucz asymetryczny przez czas trwania wywołania wykonanego do obiektu kontrapisanego.

Załóżmy na przykład, że użytkownik Alice wywołuje procedurę ProcForAlice, która wywołuje procedurę ProcSelectT1, która wybiera z tabeli T1. Alicja ma EXECUTE uprawnienia do ProcForAlice, ale nie ma EXECUTE uprawnień do ProcSelectT1 lub SELECT uprawnienia do T1, a w tym całym łańcuchu nie są zaangażowane żadne łańcuchy własności. Alicja nie może uzyskać dostępu do tabeli T1, bezpośrednio lub przy użyciu ProcForAlice i ProcSelectT1. Ponieważ chcemy, aby Alice zawsze używała ProcForAlice dostępu, nie chcemy udzielać jej uprawnień do wykonywania ProcSelectT1. Jak możemy osiągnąć ten scenariusz?

  • Jeśli podpiszemy ProcSelectT1, tak aby ProcSelectT1 mógł uzyskać dostęp do T1, alicja może wywołać ProcSelectT1 bezpośrednio i nie musi wywoływać ProcForAlice.

  • Możemy odmówić EXECUTE uprawnień do ProcSelectT1 alicji, ale następnie Alicja nie może wywołać ProcSelectT1 za pośrednictwem ProcForAlice.

  • Podpisywanie ProcForAlice nie działałoby samodzielnie, ponieważ podpis zostanie utracony w wywołaniu ProcSelectT1.

Jednak przez przypisanie ProcSelectT1 z tym samym certyfikatem używanym do podpisywania ProcForAlicepodpis jest przechowywany w łańcuchu wywołań i jest dozwolony dostęp do T1. Jeśli Alicja próbuje wywołać ProcSelectT1 bezpośrednio, nie może uzyskać dostępu do T1, ponieważ kontrasignature nie udziela żadnych praw. Przykładowy języka C pokazuje Transact-SQL dla tego przykładu.

zrzut ekranu przedstawiający przykład podpisu.

Uprawnienia

Wymaga ALTER uprawnienia do obiektu i CONTROL uprawnienia do certyfikatu lub klucza asymetrycznego. Jeśli skojarzony klucz prywatny jest chroniony hasłem, użytkownik musi również mieć hasło.

Przykłady

A. Podpisywanie procedury składowanej przy użyciu certyfikatu

Poniższy przykład podpisuje procedurę składowaną HumanResources.uspUpdateEmployeeLogin przy użyciu certyfikatu HumanResourcesDP.

USE AdventureWorks2022;

ADD SIGNATURE TO HumanResources.uspUpdateEmployeeLogin
    BY CERTIFICATE HumanResourcesDP;
GO

B. Podpisywanie procedury składowanej przy użyciu podpisanego obiektu BLOB

Poniższy przykład tworzy nową bazę danych i tworzy certyfikat do użycia w przykładzie. W przykładzie zostanie utworzona i podpisana podstawowa procedura składowana oraz pobrana sygnatura obiektu BLOB z sys.crypt_properties. Podpis zostanie następnie porzucony i dodany ponownie. Przykład podpisuje procedurę przy użyciu składni 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

Sygnatura crypt_property zwrócona przez tę instrukcję jest inna za każdym razem, gdy tworzysz procedurę. Zanotuj wynik do użycia w dalszej części tego przykładu. W tym konkretnym przypadku przedstawiony wynik jest 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. Uzyskiwanie dostępu do procedury przy użyciu kontrapisu

W poniższym przykładzie pokazano, jak kontrasygnalizowanie może pomóc w kontrolowaniu dostępu do obiektu. Musisz zastąpić <password> odpowiednim hasłem.

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