with encryption仅防普通用户查看明文代码,不防dba、sa、备份提取、内存dump等;加密后definition为空,无法alter需drop重建;mysql无此机制,仅能权限隔离+弱混淆;pg可通过security definer+视图封装隐藏逻辑;混淆非加密,运行时解密执行不可行。

SQL Server 中 WITH ENCRYPTION 能防谁?
它只阻止普通用户通过 sp_helptext 或查询系统视图(如 sys.sql_modules)直接看到明文代码,**不防 DBA、SA、备份文件提取、内存 dump 或 SQL Server 重启后的动态解密**。加密后存储过程仍可正常执行,但所有元数据中的 definition 字段变为空或乱码。
- 适用场景:防止开发同事误看/误改生产环境敏感逻辑(比如脱敏规则、内部计费公式)
- 不适用场景:合规要求“静态加密”(如等保三级)、对抗有 SA 权限的内部人员
- 加密后无法 ALTER,必须先 DROP 再 CREATE —— 这是很多人线上误操作的起点
- 示例:
CREATE PROCEDURE dbo.usp_GetUserBalance<br> @UserId INT<br>WITH ENCRYPTION<br>AS<br>BEGIN<br> SELECT Balance FROM Users WHERE Id = @UserId;<br>END
MySQL 存储过程没法加密,只能靠权限和混淆
MySQL 没有类似 WITH ENCRYPTION 的机制,SHOW CREATE PROCEDURE 始终可见源码。真正能落地的只有两件事:最小权限隔离 + 代码层面弱混淆。
- 禁止普通账号查
mysql.proc表:REVOKE SELECT ON mysql.proc FROM 'appuser'@'%'; - 用无意义变量名、拆分字符串、动态拼接 SQL(但注意
PREPARE/EXECUTE会引入注入风险) - 避免在过程里硬编码密码或密钥;改用外部参数传入或查加密配置表
- 混淆不是安全措施,只是增加阅读成本;DBA 用
SELECT body FROM mysql.proc仍能拿到原始内容
PostgreSQL 的 pg_proc.prosrc 可被视图层遮蔽
PG 没有原生加密选项,但可通过函数重写 + 安全定义器(SECURITY DEFINER)+ 视图封装,让调用者看不到底层逻辑。
- 创建
SECURITY DEFINER函数时,执行权限以函数所有者身份进行,调用者无法看到其prosrc - 把敏感逻辑封装进函数,再用视图包装一层,对外只暴露视图字段
- 必须禁用
pg_read_all_data等高权限角色给普通用户 - 注意:超级用户仍可查
pg_proc,且函数体若含RAISE NOTICE或日志输出,可能泄露线索
混淆 ≠ 加密,别碰“自研加密存储过程”的坑
有人试图用 Base64、ROT13 甚至 AES 加密整个存储过程文本,运行时再解密执行——这在 SQL 层根本不可行。SQL Server 不支持运行时动态解密并执行字符串;MySQL 的 PREPARE 只接受字符串字面量或用户变量,而加密后的内容无法安全还原为可执行语句。
- 所有“运行时解密执行”的方案,最终都退化成明文拼接,极易被 SQL 注入利用
- 混淆变量名、加空行、注释乱码,对自动化工具无效,只拖慢自己维护速度
- 真要保护逻辑,应该移出数据库:用应用层服务做核心计算,DB 只存结果或中间态
- 最常被忽略的一点:日志、审计、监控系统可能完整记录带参数的调用语句,加密过程本身没用










