不能。WITH ENCRYPTION仅混淆代码,definition字段变NULL,但内存抓取、DAC连接或旧备份仍可还原;它仅防随意查看,无法抵御有准备的逆向。

SQL Server 的 WITH ENCRYPTION 真的能防代码泄露吗?
不能。它只提供基础混淆,不是加密——sys.sql_modules 中的 definition 字段变成 NULL,但原始文本仍可能被内存抓取、DAC 连接或旧版本备份还原后读出。DBA 或高权限用户在某些条件下仍可逆向部分结构。
实际作用是阻止 casual 查看(比如开发连不上生产库时随手 sp_helptext),对有准备的逆向几乎无效。
怎么加 WITH ENCRYPTION?注意三个硬性前提
必须满足全部条件才能成功创建,否则报错 Incorrect syntax near 'WITH' 或 Cannot encrypt a procedure with deferred name resolution:
- CREATE 语句里必须写全名:用
CREATE PROCEDURE,不能先ALTER PROCEDURE再加WITH ENCRYPTION - 存储过程中不能含未解析对象(如引用了不存在的表、函数)——
SET NOCOUNT ON后面跟SELECT * FROM nonexistent_table就会失败 - 不能在加密状态下修改:一旦加了
WITH ENCRYPTION,后续ALTER PROCEDURE必须也带这个子句,否则报错Cannot alter encrypted object without source text
正确示例:
CREATE PROCEDURE dbo.GetOrderSummary
@Year INT
WITH ENCRYPTION
AS
BEGIN
SELECT COUNT(*) FROM Orders WHERE YEAR(OrderDate) = @Year;
END;加了加密后,哪些操作会突然失效?
不是所有常规运维还能照常进行。几个典型断裂点:
-
sp_helptext返回空结果,不是报错,容易误以为“没建成功” - SSMS 右键 → “修改” 生成的脚本不带原始逻辑,只留壳:
CREATE PROCEDURE ... WITH ENCRYPTION AS BEGIN END - 无法通过
sys.dm_exec_describe_first_result_set获取返回列元数据(SQL Server 2012+),需改用临时表 +SET FMTONLY OFF模拟调用 - 某些第三方审计工具依赖
sys.sql_modules.definition,加密后直接跳过该过程,可能漏报风险点
比 WITH ENCRYPTION 更靠谱的替代思路
真要保护逻辑,得换策略,而不是依赖这个开关:
- 把核心计算逻辑下推到应用层,SQL 层只做简单 CRUD 和参数化查询
- 用 CLR 存储过程封装敏感算法(需启用
TRUSTWORTHY或证书签名,但至少源码不暴露在 T-SQL 层) - 限制访问权限:收回
VIEW DEFINITION权限,比加密更直接有效;多数人根本不需要看到 SP 定义 - 如果必须留复杂逻辑在 DB,考虑用视图 + 行级安全(
CREATE SECURITY POLICY)控制数据可见性,而非藏代码
WITH ENCRYPTION 是个开关,不是保险箱。它挡不住有心人,却可能让日常维护多绕两步。真正要防的,往往不是“谁看了代码”,而是“谁执行了不该执行的逻辑”。

















