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

SQL Server 預存程序/函數加密與解密:WITH ENCRYPTION 實作與破解原理深度剖析

     編輯:關於SqlServer

SQL Server 提供 WITH ENCRYPTION 選項保護程式碼智慧財產,但這層保護在 SQL 2000/2005 可透過系統表 syscomments 的 XOR 運算反推還原。本文完整呈現加密語法、官方限制,以及經典解密預存程序 sp_decrypt 的運作原理與完整碼(僅供學習/緊急救援用途)。

一、 官方加密語法與限制

CREATE PROCEDURE dbo.sp_XML_main
    @table_name NVARCHAR(260) = '',
    @dirname NVARCHAR(20) = ''
WITH ENCRYPTION
AS
BEGIN
    -- 業務邏輯
END;
GO
  • 適用物件:PROCEDURE、FUNCTION、VIEW、TRIGGER
  • 加密後 sp_helptext、OBJECT_DEFINITION() 均回傳 NULL
  • 無法還原:官方不提供解密功能,遺失原始碼將無法修改
  • SQL 2005+ 增強加密演算法,舊版破解工具可能失效

二、 經典解密預存程序 sp_decrypt (SQL 2000 專用)

原理:syscomments.ctext 儲存加密後的 Unicode 碼點;建立同名同長度的明文佔位物件(同樣 WITH ENCRYPTION),取得其加密碼點;利用 XOR 特性:明文 XOR 密文1 = 密文2 → 明文 = 密文1 XOR 密文2 反推原始碼。

完整程式碼(節錄關鍵邏輯)

CREATE PROCEDURE sp_decrypt @objectName VARCHAR(50)
AS
BEGIN
    SET NOCOUNT ON;
    BEGIN TRAN;

    DECLARE @type CHAR(2), @parentid INT;
    SELECT @type = xtype, @parentid = parent_obj FROM sysobjects WHERE id = OBJECT_ID(@objectName);

    -- 1. 複製原加密內容到暫存表
    CREATE TABLE #temp (number INT, colid INT, ctext VARBINARY(8000), encrypted INT, status INT);
    INSERT #temp SELECT number, colid, ctext, encrypted, status FROM syscomments WHERE id = OBJECT_ID(@objectName);

    -- 2. 迴圈處理每個 number (多重加密區塊)
    DECLARE @k INT = 0, @maxNum INT = (SELECT MAX(number) FROM #temp);
    WHILE @k <= @maxNum
    BEGIN
        -- 2.1 建立同名佔位物件 (ALTER ... WITH ENCRYPTION AS PRINT 1)
        DECLARE @sql1 NVARCHAR(4000), @sql2 VARCHAR(8000), @sql3 NVARCHAR(4000);
        -- 依 @type 動態產生 CREATE/ALTER 陳述式...
        -- 省略冗長動態 SQL 組裝,核心是產生固定長度佔位碼

        -- 2.2 執行佔位物件建立,取得其加密後 ctext (syscomments 新增列)
        EXEC sp_executesql @sql3, N'@sql1 NVARCHAR(4000), @sql2 VARCHAR(8000)', @sql1, @sql2;

        -- 2.3 XOR 還原
        -- @OrigSpText1 = 原加密碼點, @OrigSpText2 = 佔位明文碼點, @OrigSpText3 = 佔位加密碼點
        -- 明文 = @OrigSpText1 XOR (@OrigSpText2 XOR @OrigSpText3)
        -- 逐字元 UNICODE 運算...
        PRINT @resultsp;  -- 輸出還原碼

        SET @k = @k + 1;
    END

    DROP TABLE #temp;
    ROLLBACK TRAN;  -- 回滾佔位物件建立,不污染系統目錄
END;
GO

三、 呼叫範例

-- 解密單一程序
EXEC sp_decrypt 'MySecretProc';

-- 批次解密所有使用者程序
DECLARE cur CURSOR FOR
SELECT name FROM sysobjects WHERE xtype = 'P' AND name <> 'sp_decrypt';
DECLARE @n SYSNAME;
OPEN cur;
FETCH NEXT FROM cur INTO @n;
WHILE @@FETCH_STATUS = 0
BEGIN
    PRINT '/*------- ' + @n + ' -------*/';
    EXEC sp_decrypt @n;
    FETCH NEXT FROM cur INTO @n;
END;
CLOSE cur; DEALLOCATE cur;

四、 安全性啟示與現代替代方案

五、 法律與道德提醒

  • 破解他人加密物件可能違反著作權法、商業秘密保護法
  • 僅在「遺失原始碼、廠商倒閉、緊急修復上線 Bug」等情況自用
  • 建立版控(Git/SVN)與程式碼審核流程,從源頭避免「只剩加密物件」的窘境
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
版本加密強度建議做法
SQL 2000弱 (XOR 可破)勿存核心演算法;改用 CLR 組件或應用層加密
SQL 2005/2008中 (RC4 + XOR)同上;啟用 TDE 保護整庫
SQL 2012+強 (AES + 鍵階層)可信任 WITH ENCRYPTION;搭配 Always Encrypted 保護敏感欄位