sql >> Databasteknik >  >> RDS >> Sqlserver

Hur man krypterar en användardefinierad funktion i SQL Server

När du skapar en användardefinierad funktion i SQL Server har du möjlighet att kryptera den.

För att skapa en användardefinierad funktion med T-SQL använder du CREATE FUNCTION 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 funktion när du använder ALTER FUNCTION .

När du krypterar en användardefinierad funktion på detta sätt konverteras funktionens text till ett obfuskerat format. Funktionens definition är inte direkt synlig i några katalogvyer. Därför kan funktionens definition inte ses av användare som inte har tillgång till systemtabeller eller databasfiler.

Exempel 1 – Inline tabellvärderad funktion med kryptering

Här är ett exempel på hur du skapar en krypterad användardefinierad funktion med tabellvärde.

CREATE FUNCTION dbo.udf_CatsByName_ITVF( @CatName varchar(70) )
    RETURNS TABLE
    WITH ENCRYPTION
AS
RETURN (
    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.

Efter att ha skapat den funktionen, nu när jag använder sys.sql_modules systemkatalogvy för att se dess definition får jag NULL.

SELECT definition 
FROM sys.sql_modules
WHERE object_id = OBJECT_ID('udf_CatsByName_ITVF');

Resultat:

+--------------+
| definition   |
|--------------|
| NULL         |
+--------------+

Och här är felmeddelandet jag får i Azure Data Studio när jag försöker skripta funktionen:

No script was returned when scripting as Create on object UserDefinedFunction

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 2 – Multi-Statement Tabell-värderad funktion med kryptering

Här är en TVF med flera påståenden som gör samma sak som den tidigare funktionen. TVF:er med flera uttalanden har en annan syntax än inline-TVF:er. På TVF:er med flera uttalanden sätter du krypteringsalternativet efter att du har angett returvariabeln.

CREATE FUNCTION [dbo].[udf_CatsByName_MSTVF]( @CatName varchar(70) )
    RETURNS @cats TABLE (
        CatId int,
        CatName varchar(70),
        Phone varchar(10)
    )
    WITH ENCRYPTION
AS
BEGIN
    INSERT INTO @cats
    SELECT 
        CatId,
        CatName,
        Phone
    FROM dbo.Cats
    WHERE CatName = @CatName;

    RETURN;
END;

GO

Exempel 3 – Skalär funktion med kryptering

Och här är ett exempel på en krypterad skalär funktion:

CREATE FUNCTION dbo.discountPrice( 
    @price DECIMAL(12,2), 
    @discount DECIMAL(12,2) 
    ) 
RETURNS DECIMAL (12,2) 
WITH ENCRYPTION
AS
BEGIN
  RETURN @price * (1 - @discount);
END;
GO

Exempel 4 – Lägg till kryptering till en befintlig funktion

Om du vill kryptera en befintlig funktion, använd ALTER FUNCTION med samma definition. Med andra ord kan jag ta det första exemplet och ersätta CREATE med ALTER .

ALTER FUNCTION dbo.udf_CatsByName_ITVF( @CatName varchar(70) )
    RETURNS TABLE
    WITH ENCRYPTION
AS
RETURN (
    SELECT 
        CatId,
        CatName,
        Phone
    FROM dbo.Cats
    WHERE CatName = @CatName
    );

GO

Detta förutsätter uppenbarligen att resten av funktionens definition är exakt densamma som den befintliga funktionen.

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 funktionen 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 5 – Lägga till flera argument

Du kan ange flera argument som en kommaseparerad lista. Till exempel, om du vill använda kryptering och du vill ange schemabindning måste du lägga till dessa som en kommaseparerad lista.

CREATE FUNCTION dbo.udf_CatsByName_ITVF( @CatName varchar(70) )
    RETURNS TABLE
    WITH SCHEMABINDING, ENCRYPTION
AS
RETURN (
    SELECT 
        CatId,
        CatName,
        Phone
    FROM dbo.Cats
    WHERE CatName = @CatName
    );

GO

Med andra ord, du anger bara WITH en gång – du behöver inte upprepa det för varje argument.

Viktiga anmärkningar

Här är några saker du bör veta om att kryptera användardefinierade funktioner i SQL Server:

  • Privilegerade användare som kan komma åt systemtabeller via DAC-porten eller direkt komma åt databasfiler kommer fortfarande att kunna se funktionens (icke-krypterade) definition.
  • 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 funktionen publiceras som en del av SQL Server-replikering.
  • CLR-funktioner kan inte krypteras.

  1. Bygga en Hot Standby på Amazon AWS med MariaDB Cluster

  2. XAMPP - MySQL stängs av oväntat

  3. Så här klusterar du dina ProxySQL-lastbalanserare

  4. MariaDB CURRENT_USER() Förklarad