在金融、政务等对数据安全要求严格的领域,前后端接口传参的明文传输存在显著安全隐患。我们团队最近在开发某金融机构的移动端应用时,就遇到了这样的需求:所有敏感字段必须使用国密算法加密传输。经过技术选型,最终确定采用SM4算法作为加解密方案。
SM4作为我国自主设计的商用分组密码标准,具有以下优势:
采用前后端分离架构实现加解密流程:
| 组件 | 技术选型 | 选择理由 |
|---|---|---|
| 前端加密库 | sm-crypto | 专为国密算法优化的轻量级库 |
| 后端实现 | Java + BouncyCastle | 提供完整的SM4算法支持 |
| 传输格式 | JSON + Base64 | 保证密文可安全传输 |
安装sm-crypto:
bash复制npm install sm-crypto --save
javascript复制import { sm4 } from 'sm-crypto'
const key = '0123456789abcdeffedcba9876543210' // 16字节密钥
function encryptData(data) {
return sm4.encrypt(JSON.stringify(data), key)
}
注意:密钥需要与后端保持一致,建议通过安全渠道分发
javascript复制async function postEncryptedData(url, data) {
const encrypted = encryptData(data)
return axios.post(url, { ciphertext: encrypted }, {
headers: { 'Content-Type': 'application/json' }
})
}
pom.xml添加BouncyCastle依赖:
xml复制<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk15on</artifactId>
<version>1.70</version>
</dependency>
java复制public class SM4Util {
private static final String ALGORITHM_NAME = "SM4";
private static final String DEFAULT_KEY = "0123456789abcdeffedcba9876543210";
public static String decrypt(String ciphertext) {
// 实现解密逻辑
// ...
}
}
java复制public class SM4MessageConverter extends AbstractHttpMessageConverter<Object> {
@Override
protected Object readInternal(Class<?> clazz, HttpInputMessage inputMessage) {
// 获取加密请求体
String encrypted = IOUtils.toString(inputMessage.getBody(), StandardCharsets.UTF_8);
// 解密处理
String decrypted = SM4Util.decrypt(encrypted);
// 转换为目标对象
return objectMapper.readValue(decrypted, clazz);
}
}
| 测试场景 | 预期结果 |
|---|---|
| 正常加密请求 | 成功解密并处理 |
| 非法密文格式 | 返回400错误 |
| 密钥不匹配 | 解密失败 |
| 空请求体 | 返回400错误 |
在4核8G的测试环境下:
建议实现方案:
实现措施:
可能原因:
本方案还可应用于:
在实际项目中,我们通过这套方案成功满足了金融监管要求。一个关键经验是:加解密密钥必须实现定期轮换,我们建立了自动化的密钥管理系统,每月自动更新密钥并保持新旧密钥的兼容期。