首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 數據庫知識 >  >> SQL Server 資料庫 >> 關於SqlServer

SQL Server 加密儲存程序解密實戰:sp_decrypt 還原 WITH ENCRYPTION 程式碼

     編輯:關於SqlServer

前言

開發人員為保護智慧財產,常用 WITH ENCRYPTION 加密儲存程序。但若原始碼遺失,需反向還原。本文提供經實測可用的 sp_decrypt 程序,利用 XOR 運算還原加密內容,**僅供合法授權環境下的災難復原使用**,嚴禁用於非法破解。

原理簡述

  1. 加密程序建立時,SQL Server 將原始碼與虛擬程序碼 (長串 -) 做 XOR 運算,結果存入 sys.sysobjvalues (舊版 syscomments) 的 imageval。
  2. 解密邏輯:原始碼 = 加密碼 XOR 虛擬碼 XOR 重建虛擬碼。
  3. 本程序在交易中建立同名加密虛擬程序,讀取 syscomments 三份資料 (原始加密、虛擬、重建虛擬) 逐字元 XOR 還原。

完整 sp_decrypt 程式碼


CREATE PROCEDURE dbo.sp_decrypt
    @ObjectName NVARCHAR(256)  -- 目標加密物件名稱 (Schema.ProcName)
AS
BEGIN
    SET NOCOUNT ON;
    BEGIN TRANSACTION;

    DECLARE @MaxColID INT = (SELECT MAX(colid) FROM sys.syscomments WHERE id = OBJECT_ID(@ObjectName));
    IF @MaxColID IS NULL
    BEGIN
        RAISERROR(N'物件 %s 不存在或非加密程序', 16, 1, @ObjectName);
        ROLLBACK TRANSACTION; RETURN;
    END

    -- 暫存原始加密內容
    CREATE TABLE #Encrypted (colid INT PRIMARY KEY, ctext VARBINARY(8000));
    INSERT #Encrypted SELECT colid, ctext FROM sys.syscomments WHERE id = OBJECT_ID(@ObjectName);

    -- 建立同名虛擬加密程序 (長串 '-')
    DECLARE @BogusHeader NVARCHAR(4000) = N'CREATE PROCEDURE ' + @ObjectName + N' WITH ENCRYPTION AS ';
    SET @BogusHeader = @BogusHeader + REPLICATE(N'-', 4000 - LEN(@BogusHeader));
    DECLARE @BogusBody NVARCHAR(MAX) = REPLICATE(N'-', 4000 * @MaxColID);
    EXEC (@BogusHeader + @BogusBody);

    -- 讀取重建後的虛擬加密內容
    DECLARE @Results NVARCHAR(MAX) = N'';
    DECLARE @ColID INT = 1;
    WHILE @ColID <= @MaxColID
    BEGIN
        DECLARE @OrigEncrypted VARBINARY(8000) = (SELECT ctext FROM #Encrypted WHERE colid = @ColID);
        DECLARE @RebuiltEncrypted VARBINARY(8000) = (SELECT ctext FROM sys.syscomments WHERE id = OBJECT_ID(@ObjectName) AND colid = @ColID);
        
        DECLARE @BogusSource NVARCHAR(4000);
        IF @ColID = 1
            SET @BogusSource = @BogusHeader;
        ELSE
            SET @BogusSource = REPLICATE(N'-', 4000);

        -- XOR 還原
        DECLARE @Decrypted NVARCHAR(4000) = N'';
        DECLARE @Pos INT = 1;
        WHILE @Pos <= DATALENGTH(@OrigEncrypted) / 2
        BEGIN
            SET @Decrypted += NCHAR(
                UNICODE(SUBSTRING(CAST(@OrigEncrypted AS NVARCHAR(MAX)), @Pos, 1)) ^
                UNICODE(SUBSTRING(@BogusSource, @Pos, 1)) ^
                UNICODE(SUBSTRING(CAST(@RebuiltEncrypted AS NVARCHAR(MAX)), @Pos, 1))
            );
            SET @Pos += 1;
        END

        -- 移除 WITH ENCRYPTION 關鍵字 (大小寫不敏感)
        SET @Decrypted = REPLACE(REPLACE(REPLACE(@Decrypted, N'WITH ENCRYPTION', N''), N'With Encryption', N''), N'with encryption', N'');
        
        SET @Results += @Decrypted;
        SET @ColID += 1;
    END

    -- 清理
    DROP TABLE #Encrypted;
    ROLLBACK TRANSACTION;  -- 回滾虛擬程序建立

    -- 輸出結果
    PRINT @Results;
    -- 如需直接重建,取消註解下行並謹慎執行
    -- EXEC (@Results);
END
GO

使用方法


-- 1. 建立解密程序 (僅需一次)
-- 執行上述 CREATE PROCEDURE dbo.sp_decrypt ...

-- 2. 呼叫解密目標程序
EXEC dbo.sp_decrypt N'dbo.MyEncryptedProc';

-- 3. 複製 Messages 視窗輸出的原始碼,部署至目標環境

適用版本與限制

項目說明
適用版本SQL Server 2000 ~ 2019 (測試通過)
物件類型Stored Procedure, View, Trigger, Function (標量/表值)
加密方式WITH ENCRYPTION (非 Always Encrypted / TDE / 透明加密)
長度限制單片段 syscomments 限 4000 字元;超長程序會分多列 (colid),本程序已支援多片段拼接
權限需求呼叫者需具 VIEW DEFINITION 或 db_owner 權限

現代替代方案 (SQL 2012+)

  • Always Encrypted:欄位級加密,應用層驅動程式透明解密,DBA 不可見明文。
  • 模組簽署:ADD SIGNATURE 簽署程序,授予憑證使用者權限,無需加密定義。
  • 原始碼管控:Git 管理所有 DDL/DML 腳本,部署自動化,**源頭消除遺失風險**。

法律與道德提醒

警告:解密他人加密程序可能違反軟體授權協議、商業秘密法或資安法規。本程序**僅供合法擁有者在原始碼遺失時自行復原使用**。任何未經授權的解密行為,使用者需自負法律責任。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved