WITH ENCRYPTION 实际是删除源码而非加密,仅阻止sp_helptext查看,防不住DBA、备份还原或内存抓取;必须显式声明且无法追加,ALTER需重写全部逻辑并再次指定WITH ENCRYPTION。

WITH ENCRYPTION 不是加密,是删源码。它只拦得住 sp_helptext,防不住 DBA、备份还原、内存抓取,更拦不住能查数据的人。
CREATE VIEW 时漏写 WITH ENCRYPTION 就等于没加
SQL Server 不会记住“这个视图该加密”,它只认语法里有没有这一整块。名字叫 vw_salary_formula_encrypted 没用,没写关键词就裸奔。
-
CREATE VIEW vw_customers WITH ENCRYPTION AS SELECT id, name FROM customers;✅ 生效 -
CREATE VIEW vw_customers AS SELECT id, name FROM customers;❌ 完全未加密,sys.sql_modules.definition可直接查到明文 - 没有
CREATE OR ALTER VIEW ... WITH ENCRYPTION简写——想加密,必须显式写出完整语句
ALTER VIEW 必须重写全部逻辑 + 再次声明 WITH ENCRYPTION
加密不是开关属性,不能“追加”或“开启”。已有视图想补上?ALTER VIEW 必须带完整 AS SELECT 部分和 WITH ENCRYPTION,否则自动解密。
- 错误做法:
ALTER VIEW vw_customers AS SELECT id, name, email FROM customers;→ 原加密失效 - 正确做法:
ALTER VIEW vw_customers WITH ENCRYPTION AS SELECT id, name, email FROM customers; - SSMS 右键“修改”直接报错
Cannot modify encrypted objects.,图形界面生成的脚本不含原始逻辑,无法回填
加密后 sp_helptext 和 sys.sql_modules.definition 全部返回 NULL
这不是权限拦截,是 SQL Server 在 CREATE 或 ALTER 时就彻底丢弃了原始文本。没存明文,自然查不到。
-
EXEC sp_helptext 'vw_customers';→ 报错Cannot view the text for this object, because it is encrypted. -
SELECT definition FROM sys.sql_modules WHERE object_id = OBJECT_ID('vw_customers');→ 返回NULL - DBA 用 DAC 连接、还原旧备份、跑
DBCC PAGE,全都无效——没密钥,因为压根没加密,只是删了
真正该做的事:别把安全押在 WITH ENCRYPTION 上
它只管“能不能看定义”,不管“能不能查数据”。用户只要能 SELECT 视图,就能拿到结果,甚至通过执行计划、IO 统计、依赖关系反推逻辑。
- 必须同步回收权限:
REVOKE VIEW DEFINITION ON vw_customers TO public; - 核心计算逻辑尽量下推到应用层,SQL 层只做简单查询
- 若必须留复杂逻辑在 DB,优先用行级安全(
CREATE SECURITY POLICY)控制数据可见性,而非藏代码

















