En SQL Server, puede cifrar un procedimiento almacenado en el momento de crearlo o puede modificarlo más tarde para incluir el cifrado.
Para crear un procedimiento almacenado con T-SQL, utiliza CREATE PROCEDURE
sintaxis. Para encriptarlo, agrega el WITH ENCRYPTION
argumento.
También puede usar el mismo argumento para cifrar un procedimiento existente al usar ALTER PROCEDURE
.
Cuando cifra un procedimiento almacenado de esta manera, el texto del procedimiento se convierte a un formato ofuscado. Su definición no es visible directamente en ninguna vista de catálogo. Por lo tanto, la definición del procedimiento 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:crear un procedimiento almacenado cifrado
Este es un ejemplo de creación de un procedimiento almacenado cifrado.
CREATE PROCEDURE dbo.usp_GetCatsByName @catname varchar(70) WITH ENCRYPTION AS 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.
Ejemplo 2:ver el resultado
Después de crear ese procedimiento, ahora cuando uso el sp_helptext
procedimiento almacenado para ver la definición del procedimiento Recibo un mensaje que me dice que está encriptado.
EXEC sp_helptext 'usp_GetCatsByName';
Resultado:
The text for object 'usp_GetCatsByName' is encrypted.
Y si uso el sys.sql_modules
vista del catálogo del sistema obtengo NULL.
SELECT definition FROM sys.sql_modules WHERE object_id = OBJECT_ID('dbo.usp_GetCatsByName');
Resultado:
+--------------+ | definition | |--------------| | NULL | +--------------+
Obtengo un resultado similar, independientemente del método T-SQL que use para tratar de obtener la definición del procedimiento.
Y este es el mensaje de error que recibo en Azure Data Studio cuando intento crear un script para el procedimiento:
No script was returned when scripting as Create on object StoredProcedure
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 3:agregar cifrado a un procedimiento almacenado existente
Si desea encriptar un procedimiento almacenado existente, use ALTER PROCEDURE
con la misma definición. En otras palabras, puedo tomar el primer ejemplo y reemplazar CREATE
con ALTER
.
ALTER PROCEDURE dbo.usp_GetCatsByName @catname varchar(70) WITH ENCRYPTION AS SELECT CatId, CatName, Phone FROM dbo.Cats WHERE CatName = @catname; GO
Esto obviamente asume que el resto de la definición del procedimiento es exactamente igual a la 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 del procedimiento 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 4:eliminar el cifrado de un procedimiento almacenado
Podemos eliminar el cifrado ejecutando ALTER PROCEDURE
declaración sin la opción de encriptación.
ALTER PROCEDURE dbo.usp_GetCatsByName @catname varchar(70) AS SELECT CatId, CatName, Phone FROM dbo.Cats WHERE CatName = @catname;
Tenga en cuenta que esto no es lo mismo que descifrar el procedimiento almacenado. Aquí, simplemente estamos alterando el procedimiento existente a la nueva definición. Por lo tanto, se supone que ya tiene una copia del procedimiento existente en algún lugar de su control de código fuente.
Ejemplo 5:Procedimientos almacenados compilados de forma nativa
El cifrado no es compatible con los procedimientos almacenados compilados de forma nativa.
Esto es lo que sucede cuando intento cifrar un procedimiento almacenado compilado de forma nativa:
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;
Resultado:
Msg 10794, Level 16, State 17, Procedure usp_GetCowsByName, Line 3 The option 'ENCRYPTION' is not supported with natively compiled modules.
Ese procedimiento de ejemplo está tomado de mi artículo, Cómo crear un procedimiento almacenado vinculado a un esquema en SQL Server, que también explica que tampoco puede vincular un procedimiento almacenado a un esquema si no es un procedimiento compilado de forma nativa.
Notas importantes
Aquí hay algunas cosas que debe saber sobre el cifrado de procedimientos almacenados 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 del procedimiento almacenado (no cifrado).
- 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 de cifrado evita que el procedimiento se publique como parte de la replicación de SQL Server.
- Los procedimientos CLR no se pueden cifrar.
- Los procedimientos compilados de forma nativa no se pueden cifrar.