sql >> Base de Datos >  >> RDS >> Sqlserver

Cómo cifrar una función definida por el usuario en SQL Server

Al crear una función definida por el usuario en SQL Server, tiene la opción de cifrarla.

Para crear una función definida por el usuario con T-SQL, utilice CREATE FUNCTION sintaxis. Para encriptarlo, agrega el WITH ENCRYPTION argumento.

También puede usar el mismo argumento para cifrar una función existente al usar ALTER FUNCTION .

Cuando cifra una función definida por el usuario de esta manera, el texto de la función se convierte a un formato ofuscado. La definición de la función no es directamente visible en ninguna vista de catálogo. Por lo tanto, la definición de la función no puede ser vista por usuarios que no tengan acceso a las tablas del sistema o a los archivos de la base de datos.

Ejemplo 1:función con valores de tabla en línea con cifrado

Este es un ejemplo de cómo crear una función cifrada con valores de tabla definida por el usuario.

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

La parte para cifrarlo es WITH ENCRYPTION . Simplemente podría eliminar ese argumento si no quisiera cifrarlo.

Después de crear esa función, ahora cuando uso sys.sql_modules vista de catálogo del sistema para ver su definición, obtengo NULL.

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

Resultado:

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

Y este es el mensaje de error que recibo en Azure Data Studio cuando intento crear un script para la función:

No script was returned when scripting as Create on object UserDefinedFunction

Y recibiría un mensaje similar si intentara verlo en SSMS, DBeaver o cualquier otro software de administración de base de datos GUI.

Ejemplo 2:función con valores de tabla de declaraciones múltiples con cifrado

Aquí hay un TVF de declaraciones múltiples que hace lo mismo que la función anterior. Los TVF de declaraciones múltiples tienen una sintaxis diferente a los TVF en línea. En los TVF de declaraciones múltiples, coloca la opción de cifrado después de especificar la variable de retorno.

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

Ejemplo 3:función escalar con cifrado

Y aquí hay un ejemplo de una función escalar encriptada:

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

Ejemplo 4:agregar cifrado a una función existente

Si desea encriptar una función existente, use ALTER FUNCTION con la misma definición. En otras palabras, puedo tomar el primer ejemplo y reemplazar CREATE con 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

Obviamente, esto supone que el resto de la definición de la función es exactamente igual a la función existente.

La forma más fácil de asegurarse de que está usando la misma definición es usar su herramienta GUI para crear un script de la función existente usando la opción "Script as Alter", si existe. De lo contrario, podría usar "Script como Create", luego, cuando aparezca la definición, cambie CREATE con ALTER .

Si solo tiene una interfaz de línea de comandos, puede consultar sys.sql_modules view para obtener la definición existente (como en el ejemplo anterior). Luego puede copiar la definición y reemplazar CREATE con ALTER .

Una vez que haya hecho eso, puede agregar WITH ENCRYPTION y ejecutarlo de nuevo.

Ejemplo 5:agregar varios argumentos

Puede especificar varios argumentos como una lista separada por comas. Por ejemplo, si desea utilizar el cifrado y desea especificar el enlace de esquema, entonces deberá agregarlos como una lista separada por comas.

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

En otras palabras, solo especifica WITH una vez, no es necesario repetirlo para cada argumento.

Notas importantes

Aquí hay algunas cosas que debe saber sobre el cifrado de funciones definidas por el usuario en SQL Server:

  • Los usuarios privilegiados que pueden acceder a las tablas del sistema a través del puerto DAC o acceder directamente a los archivos de la base de datos aún podrán ver la definición de la función (no cifrada).
  • Los usuarios que pueden adjuntar un depurador al proceso del servidor pueden recuperar el procedimiento original de la memoria en tiempo de ejecución.
  • El uso del cifrado evita que la función se publique como parte de la replicación de SQL Server.
  • Las funciones CLR no se pueden cifrar.