DSPM 集成加密接口架构设计:分层、解耦、抽象
这一章咱们聊聊架构。实话实说,很多团队做加密集成,上来就写一个「加解密工具类」,然后在业务代码里到处调。短期看很爽,长期来看……嗯,你会发现自己被绑死在某个加密厂商上了。我曾经见过一个项目,仅仅因为换了一家 HSM 供应商,折腾了将近两个月。
所以这一节,我带你看看怎么从根上把架构搭稳。核心就三个词:分层、解耦、抽象。说白了,就是用一套合理的架子,把「业务代码」和「加密细节」彻底隔开。
4.1 分层架构:三层其实刚刚好
很多教科书喜欢画四五层。但以我的经验,DSPM 加密接口这块,三层就够了,多了反而容易把性能拖垮。
- 接入层(API Gateway / RPC):负责协议转换、认证、限流。它不处理任何加密逻辑,只是把请求丢给下一层。
- 服务编排层(Orchestrator):这是最复杂的层。它决定「用哪个加密算法」「从哪获取密钥」「要不要做字段级别的分级加密」。我个人习惯把业务逻辑和加密策略都写在这里,但绝不让它直接调底层驱动的 API。
- 加密引擎层(Engine):纯技术的黑盒。它只做一件事:输入明文+密钥ID,输出密文;或者反过来。至于密钥存在哪、用的是软加密还是硬加密,它自己搞定。
为什么是三层?你想想看,如果哪天你要把 AES-256-GCM 换成国密 SM4,只需要改最下面那层。上面两层根本不知道下面换了什么。
4.2 服务与接口解耦:别让「依赖」变成「绑架」
分层是骨架,解耦才是灵魂。很多同学会问:分了三层之后,层与层之间到底怎么通信才叫「解耦」?
答案很简单:用接口,别用实现。每一层只依赖一个抽象接口,而不是一个具体的加密厂商 SDK。
| 做法 | 耦合度 | 换厂商成本 | 我的评价 |
|---|---|---|---|
| 直接在业务代码里调 Vault API | 极高 | 大范围改代码 | 千万别这么干 |
| 封装一层 XxxEncryptUtil | 中等 | 改 Util 类+回归测试 | 过渡方案,能用但不好 |
| 定义标准接口,通过 SPI 加载 | 低 | 新增一个 jar 包即可 | 个人最推荐 |
具体怎么解耦?我建议用 命令查询职责分离(CQRS) 的思路来设计接口:
// 加密命令
public interface EncryptCommand {
EncryptResult encrypt(EncryptRequest request);
}
// 解密命令
public interface DecryptCommand {
DecryptResult decrypt(DecryptRequest request);
}
// 密钥查询(非变更操作)
public interface KeyQueryService {
KeyMeta getKeyMeta(String keyId);
boolean isKeyRotated(String keyId);
}
为什么要拆成三个接口?因为「加密」和「查询密钥元数据」是完全不同的 QPS 和隔离级别。在线上环境,我曾经把它们合在一个接口里,结果一次密钥查询的慢 SQL 把加密链路也拖垮了。分开之后,查询慢了只影响管理台,不影响核心加解密链路。
4.3 加密引擎抽象:把「怎么做」藏在背后
加密引擎是整个系统的核心。但它的设计原则恰恰相反——对调用方来说,它应该越简单越好。
怎么抽象?我一般会用 策略模式 + 工厂模式。调用方只需要告诉引擎:「我要加密,这是数据,这是密钥 ID」。至于引擎内部是走软加密还是硬加密,用 AES 还是 SM4,调用方完全不用关心。
来看看具体的抽象层设计:
public interface CryptoEngine {
// 初始化引擎(加载驱动、建立连接池)
void init(EngineConfig config);
// 加密
byte[] encrypt(byte[] plaintext, String keyId, CryptoContext context);
// 解密
byte[] decrypt(byte[] ciphertext, String keyId, CryptoContext context);
// 健康检查(高可用必备)
boolean healthCheck();
// 优雅关闭
void shutdown();
}
这里有个关键点:CryptoContext。它里面放的是算法偏好、安全等级、是否走 FIPS 模式这类信息。我习惯把这部分信息从业务请求里剥离出来,放到一个上下文对象中。原因是业务代码不应该知道「哦,这个商户要用 FIPS 模式」,它只需要告诉引擎「这个请求的敏感级别是 L3」就够了。
4.4 架构总览:一张图看懂
说完了三层、解耦、抽象,我用一张 SVG 图把它们串起来。这张图是我做架构评审时最爱画的,简单直接,一眼就能看出请求怎么走,依赖怎么隔离。
这张图画得很清楚。从上到下,请求流动路径一目了然。我特别喜欢在说明框里强调「可插拔」——这也是整个架构设计最核心的追求。你只要把这张图上的逻辑落地了,后续不管是加集群、换加密卡、还是应对合规审计,都会从容很多。