SQL Server: With Encryption - Como ler

Existem alguns objetos nos databases SQL Server que podem ser encriptados a fim de proteger a sua lógica de negócios:

  • procedures;
  • views;
  • functions;
  • triggers.

Quando criamos um desses objetos podemos usar a cláusula WITH ENCRYPTION, que aplica criptografia ao conteúdo do objeto. Ele continua funcionando normalmente, mas não pode ter o código lido.

CREATE DATABASE EXEMPLO
GO

USE 
EXEMPLO
GO
CREATE PROC 
USP_PROCEDURE
    @VALOR 
VARCHAR(10)
AS
    SELECT CONVERT
(VARCHARGETDATE(), 103AS 'DATA_ATUAL'
        
CONVERT(VARCHARGETDATE(), 108AS 'HORA_ATUAL'
        
UPPER(@VALOR) AS 'CONTEUDO_DE_VALOR'
GO

EXEC 
SP_HELP USP_PROCEDURE
/*
Name           Owner  Type              Created_datetime         
-------------- ------ ----------------- ------------------------ 
USP_PROCEDURE  dbo    stored procedure  2010-05-19 07:29:29.150

Parameter_name  Type     Length Prec  Scale  Param_order Collation                  
--------------- -------- ------ ----- ------ ----------- ---------------------------
@VALOR          varchar  10     10    NULL   1           Latin1_General_CI_AS_KS_WS
*/

EXEC SP_HELPTEXT USP_PROCEDURE
/*
Text                                                                                                                                                                                                                                                            
------------------------------------------------------------------
CREATE PROC USP_PROCEDURE
    @VALOR VARCHAR(10)
AS
    SELECT CONVERT(VARCHAR, GETDATE(), 103) AS 'DATA_ATUAL', 
        CONVERT(VARCHAR, GETDATE(), 108) AS 'HORA_ATUAL', 
        UPPER(@VALOR) AS 'CONTEUDO_DE_VALOR'
*/
EXEC USP_PROCEDURE 'algo'
/*
DATA_ATUAL  HORA_ATUAL  CONTEUDO_DE_VALOR 
----------- ----------- ----------------- 
19/05/2010  07:29:30    ALGO
*/

GO

ALTER PROC 
USP_PROCEDURE
    @VALOR 
VARCHAR(10)
WITH ENCRYPTION
AS
    SELECT CONVERT
(VARCHARGETDATE(), 103AS 'DATA_ATUAL'
        
CONVERT(VARCHARGETDATE(), 108AS 'HORA_ATUAL'
        
UPPER(@VALOR) AS 'CONTEUDO_DE_VALOR'
GO

EXEC 
SP_HELP USP_PROCEDURE
/*
Name           Owner  Type              Created_datetime         
-------------- ------ ----------------- ------------------------ 
USP_PROCEDURE  dbo    stored procedure  2010-05-19 07:29:29.150

Parameter_name  Type     Length Prec  Scale  Param_order Collation                  
--------------- -------- ------ ----- ------ ----------- ---------------------------
@VALOR          varchar  10     10    NULL   1           Latin1_General_CI_AS_KS_WS
*/

EXEC SP_HELPTEXT USP_PROCEDURE
/*
The object comments have been encrypted.
*/

EXEC USP_PROCEDURE 'algo'
/*
DATA_ATUAL  HORA_ATUAL  CONTEUDO_DE_VALOR 
----------- ----------- ----------------- 
19/05/2010  07:29:57    ALGO
*/

Você pode observar que a procedure sp_help sempre traz o mesmo conteúdo e a execução também não é prejudicada pela criptografia. Claro... senão não teria nenhum sentido criptografar um objeto...

Somente o sp_helptext é que tem o comportamento alterado: para objetos criptografados ele traz uma mensagem "o objeto está criptografado".

Como existem sutis diferenças entre a segurança do SQL Server 2000, 2005 e 2008, vou começar explicando como funciona no SQL Server 2000. Depois, com tempo, vou acrescentando material para as novas versões.

O algoritmo usado nessa criptografia é o XOR (eXclusive OR - ou exclusivo), que trabalha com a informação bit-a-bit, comparando dois valores e retornando o valor 1 se eles forem diferentes (exclusivos) ou 0 se eles forem iguais.

Por exemplo:

select as '6 XOR 4'
/*
6 XOR 4     
----------- 
2
*/

Na realidade, o que acontece é que o algoritmo XOR decompõe o número 6 e o número 4 em binário e trabalha com eles da seguinte forma:

6 ->       00000000 00000000 00000000 00000110
4 ->       00000000 00000000 00000000 00000100
           -----------------------------------
6^4 ->     00000000 00000000 00000000 00000010 -> 2

E o mais interessante é que o XOR é simétrico, isto é: a mesma chave usada para criptografar a mensagem é usada para decriptar. Isso quer dizer que se eu aplicar a chave à mensagem criptografada obtenho a mensagem original:

select as '2 XOR 4'
/*
2 XOR 4     
----------- 
6
*/
2 ->       00000000 00000000 00000000 00000010
4 ->       00000000 00000000 00000000 00000100
           -----------------------------------
2^4 ->     00000000 00000000 00000000 00000110 -> 6

Para deixar claro, quando estudamos criptografia, vemos os seguintes termos:

  • Mensagem - o texto ou valor original, que pode ser lido sem problemas (o valor 6, no exemplo acima);
  • chave - uma sequência de bits usado para criptografar a mensagem (o valor 4, no exemplo acima);
  • algoritmo - sequência de passos que são realizados para criptografar a mensagem, usando a chave;
  • mensagem cifrada - a mensagem original depois de aplicado o algoritmo (o valor 2, no exemplo acima);
  • emissor - quem envia a mensagem;
  • receptor - quem recebe a mensagem;
  • criptografia - ato de criptografar (alterar a mensagem usando a chave);
  • decriptação - ato de decriptar (obter a mensagem a partir da mensagem cifrada e chave).

E, voltando ao SQL Server, temos que os objetos do banco (os quatro citados anteriormente) tem suas propriedades armazenadas nas seguintes tabelas (existem outras, mas não vem ao caso:

  • sysobjects - definição do objeto;
  • syscolumns - definição das colunas do objeto (ou argumentos, no caso de procedures e functions);
  • syscomments - corpo do objeto (lógica).

Dentro da syscomments temos duas colunas que nos interessa:

  • text - o código, em Unicode;
  • ctext - o código transformado em binário.
SELECT ID
    CTEXT, 
    
TEXT 
FROM 
SYSCOMMENTS 
WHERE ID = OBJECT_ID('USP_PROCEDURE')
/*
--com o objeto sem criptografia
ID          CTEXT             TEXT
----------- ----------------- -----------------------------
1977058079  0x435245415445... CREATE PROC USP_PROCEDURE...

--com o objeto criptografado
ID          CTEXT             TEXT                
----------- ----------------- --------------------
1977058079  0xF879595BA43...  ????????????????...
*/

Com isso em mente, podemos imaginar o seguinte: se eu criptografar um texto qualquer e fizer um XOR com o texto original, tenho a chave (no exemplo acima, eu faria 6 ^ 4 = 2, onde 2 é a chave)... aí, com a chave, consigo obter o original de novo!!!

E o código ficou assim:

CREATE PROCEDURE USP_DECRIPTA_OBJETO 
    @NOME_OBJETO 
VARCHAR(50)
AS
    SET 
ANSI_WARNINGS OFF

    DECLARE 
@CTEXT_ORIGINAL NVARCHAR(4000), 
        @COMANDO 
NVARCHAR(4000), 
        @CTEXT_NOVO 
NVARCHAR(4000), 
        @COMANDO_NOVO 
NVARCHAR(4000), 
        @CONTADOR 
INT
     
    SELECT 
@CTEXT_ORIGINAL CTEXT 
    
FROM SYSCOMMENTS 
    
WHERE ID = OBJECT_ID(@NOME_OBJETO)
     
    
SET @COMANDO 'ALTER PROCEDURE '
    
+ @NOME_OBJETO 
    + 
' WITH ENCRYPTION AS '
    
+ REPLICATE('-'4000 62)

    
EXECUTE (@COMANDO)
     
    
SELECT @CTEXT_NOVO CTEXT 
    
FROM SYSCOMMENTS 
    
WHERE ID = OBJECT_ID(@NOME_OBJETO)
     
    
SET @COMANDO='CREATE PROCEDURE '
    
+ @NOME_OBJETO 
    + 
' WITH ENCRYPTION AS '
    
+ REPLICATE('-'4000 62)
     
    
SET @CONTADOR 1
     
    
SET @COMANDO_NOVO REPLICATE(N'A'
        (
DATALENGTH(@CTEXT_ORIGINAL) / 2))
     
    
WHILE @CONTADOR <= DATALENGTH(@CTEXT_ORIGINAL)/2
    
BEGIN
        SET 
@COMANDO_NOVO STUFF(@COMANDO_NOVO, @CONTADOR, 1,
        
NCHAR(UNICODE(SUBSTRING(@CTEXT_ORIGINAL, @CONTADOR, 1)) ^
        (UNICODE(
SUBSTRING(@COMANDO, @CONTADOR, 1)) ^
        UNICODE(
SUBSTRING(@CTEXT_NOVO, @CONTADOR, 1)))))

        
SET @CONTADOR=@CONTADOR+1
    
END

    EXECUTE
('DROP PROCEDURE ' + @NOME_OBJETO)

    
IF CHARINDEX('WITH ENCRYPTION'UPPER(@COMANDO_NOVO)) > 0
        
SET @COMANDO_NOVO = REPLACE(UPPER(@COMANDO_NOVO), 'WITH ENCRYPTION''')

    
EXECUTE(@COMANDO_NOVO)
GO

Agora, sim!!! é só descompilar as procedures e ver o seu conteúdo...

OBS.: eu já tinha postado isso em 2006, no site da DevMedia, mas como alguém tocou nesse assunto esses dias atrás, achei adequado refazer o post.

 

Comentários (1) -

Leonardo Breda
Leonardo Breda
20/05/2010 09:03:10 #

Olha aí o professor dando aula de Álgebra Booleana.

Agnaldo, já vi DBA (repito: DBA!!!) dizendo que tem dificuldades em misturar AND, OR, XOR, NOT e NAND!
Se ele tivesse feito um curso de eletrônica digital, ele aprenderia como isso funciona internamente...
É basicamente isso aqui: whatis.techtarget.com/.../...id9_gci213512,00.html

Comentar

  Country flag

biuquote
  • Comentário
  • Pré-visualização
Loading