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、TRIGGERsp_helptext、OBJECT_DEFINITION() 均回傳 NULL原理: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;
| 版本 | 加密強度 | 建議做法 |
|---|---|---|
| SQL 2000 | 弱 (XOR 可破) | 勿存核心演算法;改用 CLR 組件或應用層加密 |
| SQL 2005/2008 | 中 (RC4 + XOR) | 同上;啟用 TDE 保護整庫 |
| SQL 2012+ | 強 (AES + 鍵階層) | 可信任 WITH ENCRYPTION;搭配 Always Encrypted 保護敏感欄位 |