I SQL Server kan du kryptera en lagrad procedur när du skapar den, eller så kan du ändra den senare för att inkludera kryptering.
För att skapa en lagrad procedur med T-SQL använder du CREATE PROCEDURE
syntax. För att kryptera den lägger du till WITH ENCRYPTION
argument.
Du kan också använda samma argument för att kryptera en befintlig procedur när du använder ALTER PROCEDURE
.
När du krypterar en lagrad procedur på det här sättet konverteras procedurens text till ett obfuskerat format. Dess definition är inte direkt synlig i några katalogvyer. Därför kan procedurens definition inte ses av användare som inte har tillgång till systemtabeller eller databasfiler.
Exempel 1 – Skapa en krypterad lagrad procedur
Här är ett exempel på hur du skapar en krypterad lagrad procedur.
CREATE PROCEDURE dbo.usp_GetCatsByName @catname varchar(70) WITH ENCRYPTION AS SELECT CatId, CatName, Phone FROM dbo.Cats WHERE CatName = @catname; GO
Delen för att kryptera den är WITH ENCRYPTION
. Jag kunde helt enkelt ta bort det argumentet om jag inte ville kryptera det.
Exempel 2 – Se resultatet
Efter att ha skapat den proceduren, nu när jag använder sp_helptext
lagrad procedur för att se procedurens definition Jag får ett meddelande som talar om för mig att den är krypterad.
EXEC sp_helptext 'usp_GetCatsByName';
Resultat:
The text for object 'usp_GetCatsByName' is encrypted.
Och om jag använder sys.sql_modules
systemkatalogvy Jag får NULL.
SELECT definition FROM sys.sql_modules WHERE object_id = OBJECT_ID('dbo.usp_GetCatsByName');
Resultat:
+--------------+ | definition | |--------------| | NULL | +--------------+
Jag får ett liknande resultat, oavsett vilken T-SQL-metod jag använder för att försöka få procedurens definition.
Och här är felmeddelandet jag får i Azure Data Studio när jag försöker skripta proceduren:
No script was returned when scripting as Create on object StoredProcedure
Och jag skulle få ett liknande meddelande om jag försökte visa det i SSMS, DBeaver eller någon annan programvara för GUI-databashantering.
Exempel 3 – Lägg till kryptering till en befintlig lagrad procedur
Om du vill kryptera en befintlig lagrad procedur, använd ALTER PROCEDURE
med samma definition. Med andra ord kan jag ta det första exemplet och ersätta CREATE
med ALTER
.
ALTER PROCEDURE dbo.usp_GetCatsByName @catname varchar(70) WITH ENCRYPTION AS SELECT CatId, CatName, Phone FROM dbo.Cats WHERE CatName = @catname; GO
Detta förutsätter uppenbarligen att resten av procedurens definition är exakt densamma som den befintliga.
Det enklaste sättet att säkerställa att du använder samma definition är att använda ditt GUI-verktyg för att skripta den befintliga proceduren med alternativet "Script as Alter", om det finns. Annars kan du använda "Skript som Skapa", och sedan ändra CREATE
när definitionen visas med ALTER
.
Om du bara har ett kommandoradsgränssnitt kan du fråga sys.sql_modules
visa för att få den befintliga definitionen (som i föregående exempel). Du kan sedan kopiera definitionen och ersätta CREATE
med ALTER
.
När du har gjort det kan du lägga till WITH ENCRYPTION
och kör det igen.
Exempel 4 – Ta bort kryptering från en lagrad procedur
Vi kan ta bort kryptering genom att köra ALTER PROCEDURE
uttalande utan krypteringsalternativet.
ALTER PROCEDURE dbo.usp_GetCatsByName @catname varchar(70) AS SELECT CatId, CatName, Phone FROM dbo.Cats WHERE CatName = @catname;
Observera att detta inte är samma sak som att dekryptera den lagrade proceduren. Här ändrar vi helt enkelt den befintliga proceduren till den nya definitionen. Så det förutsätter att du redan har en kopia av den befintliga proceduren någonstans i din källkontroll.
Exempel 5 – Inbyggt kompilerade lagrade procedurer
Kryptering stöds inte på inbyggt kompilerade lagrade procedurer.
Här är vad som händer när jag försöker kryptera en inbyggt kompilerad lagrad procedur:
ALTER PROCEDURE [dbo].[usp_GetCowsByName] @cowname varchar(70) WITH SCHEMABINDING, NATIVE_COMPILATION, ENCRYPTION AS BEGIN ATOMIC WITH ( TRANSACTION ISOLATION LEVEL = SNAPSHOT, LANGUAGE = N'us_english' ) SELECT CowId, CowName, Phone FROM dbo.Cows WHERE CowName = @cowname END;
Resultat:
Msg 10794, Level 16, State 17, Procedure usp_GetCowsByName, Line 3 The option 'ENCRYPTION' is not supported with natively compiled modules.
Den exempelproceduren är hämtad från min artikel, How to Create a Schema Bound Stored Procedure in SQL Server, som också förklarar att du inte heller kan schemabundna en lagrad procedur om det inte är en inbyggt kompilerad procedur.
Viktiga anmärkningar
Här är några saker du bör veta om kryptering av lagrade procedurer i SQL Server:
- Privilegerade användare som kan komma åt systemtabeller via DAC-porten eller direkt komma åt databasfiler kommer fortfarande att kunna se definitionen av den lagrade proceduren (icke-krypterad).
- Användare som kan koppla en debugger till serverprocessen kan hämta den ursprungliga proceduren från minnet vid körning.
- Användning av kryptering förhindrar att proceduren publiceras som en del av SQL Server-replikering.
- CLR-procedurer kan inte krypteras.
- Inbyggt kompilerade procedurer kan inte krypteras.