with encryption 并非真正加密,而是删除源码;它仅阻止 sp_helptext 查看,无法防 dba、备份还原或内存抓取,且必须在 create/alter 时显式声明才生效。

WITH ENCRYPTION 不是加密,是删源码;它防不住 DBA、备份还原或内存抓取,只拦得住随手 sp_helptext 的人。
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)控制数据可见性,而非藏代码 - 所有带
WITH ENCRYPTION的视图,源码必须存 Git,部署脚本中显式加上该子句——加密后无法从数据库找回
最常被忽略的一点:加密后你再也无法靠数据库自身做 diff 或审计变更,一旦本地脚本丢失,紧急修复只能靠记忆或执行计划反推字段,非常被动。











