LÄGG TILL SIGNATUR (Transact-SQL)
gäller för:SQL Server
Azure SQL Database
Azure SQL Managed Instance
Lägger till en digital signatur i en lagrad procedur, funktion, sammansättning eller DML-utlösare. Lägger också till en motsignatur i en lagrad procedur, funktion, sammansättning eller DML-utlösare.
Transact-SQL syntaxkonventioner
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
Argument
module_class
Klassen för modulen som signaturen läggs till i. Standardvärdet för moduler med schemaomfattning är OBJECT
.
module_name
Namnet på en lagrad procedur, funktion, sammansättning eller utlösare som ska signeras eller kontrasigneras.
CERTIFIKAT cert_name
Namnet på ett certifikat som den lagrade proceduren, funktionen, sammansättningen eller utlösaren ska signeras eller mottilldelas med.
MED LÖSENORD =lösenord
Lösenordet som krävs för att dekryptera den privata nyckeln för certifikatet eller den asymmetriska nyckeln. Den här satsen krävs bara om den privata nyckeln inte skyddas av databashuvudnyckeln.
SIGNATURE = signed_blob
Anger modulens signerade, binära stora objekt (BLOB). Den här satsen är användbar om du vill skicka en modul utan att skicka den privata nyckeln. När du använder den här satsen krävs endast modulen, signaturen och den offentliga nyckeln för att lägga till det signerade binära stora objektet i en databas. signed_blob är själva bloben i hexadecimalt format.
ASYMMETRISK NYCKEL Asym_Key_Name
Namnet på en asymmetrisk nyckel som den lagrade proceduren, funktionen, sammansättningen eller utlösaren ska signeras med eller motsignas med.
Anmärkningar
Modulen som signeras eller kontrasigneras och certifikatet eller den asymmetriska nyckel som används för att signera den måste redan finnas. Varje tecken i modulen ingår i signaturberäkningen. Detta inkluderar inledande vagnreturer och linjefeeds.
En modul kan signeras och kontrasigneras av valfritt antal certifikat och asymmetriska nycklar.
Signaturen för en modul tas bort när modulen ändras.
Om en modul innehåller en EXECUTE AS
-sats inkluderas även säkerhets-ID (SID) för huvudkontot som en del av signeringsprocessen.
Försiktighet
Modulsignering bör endast användas för att bevilja behörigheter, aldrig för att neka eller återkalla behörigheter.
DDL-utlösare (Data Definition Language) och Inline table-valued functions kan inte signeras.
Information om signaturer visas i sys.crypt_properties
katalogvyn.
Varning
När du återskapar en procedur för signatur måste alla instruktioner i den ursprungliga batchen matcha den återskapade batchen. Om någon del av batchen skiljer sig åt, även i blanksteg eller kommentarer, skiljer sig den resulterande signaturen.
Motsigneringar
När du kör en signerad modul läggs signaturerna tillfälligt till i SQL-token, men signaturerna går förlorade om modulen kör en annan modul eller om modulen avslutar körningen. En motsignering är en särskild form av signatur. I sig beviljar inte en motsignatur några behörigheter. Det gör dock att signaturer som görs av samma certifikat eller asymmetriska nyckel kan behållas under hela anropet till det motsignerade objektet.
Anta till exempel att användaren Alice
anropar proceduren ProcForAlice
, som anropar proceduren ProcSelectT1
, som väljer från tabellen T1
. Alice har EXECUTE
behörighet på ProcForAlice
, men har inte EXECUTE
behörigheter för ProcSelectT1
eller SELECT
behörighet på T1
, och ingen ägarskapslänkning ingår i hela den här kedjan. Alice kan inte komma åt tabell T1
, antingen direkt eller med hjälp av ProcForAlice
och ProcSelectT1
. Eftersom vi vill att Alice alltid ska använda ProcForAlice
för åtkomst vill vi inte ge henne behörighet att köra ProcSelectT1
. Hur kan vi åstadkomma det här scenariot?
Om vi signerar
ProcSelectT1
, så attProcSelectT1
kan komma åtT1
, kan Alice anropaProcSelectT1
direkt och hon behöver inte anropaProcForAlice
.Vi kan neka
EXECUTE
behörighet förProcSelectT1
till Alice, men sedan kan Alice inte anropaProcSelectT1
viaProcForAlice
.Att signera
ProcForAlice
fungerar inte på egen hand eftersom signaturen går förlorad i anropet tillProcSelectT1
.
Men genom att kontrasignera ProcSelectT1
med samma certifikat som används för att signera ProcForAlice
behålls signaturen i anropskedjan och får åtkomst till T1
. Om Alice försöker anropa ProcSelectT1
direkt kan hon inte komma åt T1
eftersom motsignaturen inte beviljar några rättigheter.
Exempel C visar Transact-SQL för det här exemplet.
Behörigheter
Kräver ALTER
behörighet för objektet och CONTROL
behörighet för certifikatet eller asymmetrisk nyckel. Om en associerad privat nyckel skyddas av ett lösenord måste användaren också ha lösenordet.
Exempel
A. Signera en lagrad procedur med hjälp av ett certifikat
I följande exempel signeras den lagrade proceduren HumanResources.uspUpdateEmployeeLogin
med certifikatet HumanResourcesDP
.
USE AdventureWorks2022;
ADD SIGNATURE TO HumanResources.uspUpdateEmployeeLogin
BY CERTIFICATE HumanResourcesDP;
GO
B. Signera en lagrad procedur med hjälp av en signerad BLOB
I följande exempel skapas en ny databas och ett certifikat skapas som ska användas i exemplet. Exemplet skapar och signerar en grundläggande lagrad procedur och hämtar signaturbloben från sys.crypt_properties
. Signaturen tas sedan bort och läggs till igen. Exemplet signerar proceduren med hjälp av syntaxen 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
Den crypt_property
signatur som returneras av den här instruktionen skiljer sig åt varje gång du skapar en procedur. Anteckna resultatet för användning senare i det här exemplet. I det här fallet är resultatet som visas 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. Få åtkomst till en procedur med hjälp av en motsignering
I följande exempel visas hur motsignering kan hjälpa dig att styra åtkomsten till ett objekt. Du måste ersätta <password>
med ett lämpligt lösenord.
-- 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;