JS 处理生僻字字符 sm4 加密后 Java 解密字符乱码问题

前言

这个问题是一个个例,不具备普适性,但为啥仍然拿出来呢?

主要还是想和大家分享一个排查问题的思路的方式,一步一步的缩小问题范围,最终确定问题所在。

最近在做一个生僻字相关的需求:对接生僻字键盘,支持输入生僻字,并完成生僻字传输,落库,查询,反显等一系列动作。

对接生僻字键盘上的工作倒是不复杂,结果问题出在了生僻字传输这一步上。

部分生僻字通过国密加密后到服务端解密显示就是 ?了,这也直接导致落库后的内容是一个错乱字符,反显自然也有问题

分析原因

阶段一

梳理整个数据传输流程:

flowchart TD A[前端数据采集] --> B[前端加密处理] B --> C[网络传输] C --> D[后端接收数据] D --> E[后端解密处理] E --> F{字符编码检查} F -->|编码不一致| G[出现乱码] F -->|编码一致| H[正常显示数据]

初步判断,与加解密有关

  • 尝试明文传输生僻字字符串到后端,落库,反显一切正常
  • 尝试对生僻字字符进行 Unicode 转换,再进行加密传输,后端解密,落库,查询后通过 Unicode 还原,反显一切正常

这两步试验明确了原生僻字字符直接进行国密加密后会导致后端解密失败,文字变成 ?

同组的小伙伴排查到这里之后,选择直接使用第二种尝试进行业务实现,就是转 Unicode 的方案。

这样虽然可以解决当前的问题,但是也意味着所有需要显示生僻字的渠道场景,都需要做 Unicode 字符解析的动作才能正常展示这些字段,牵扯的系统比较多,改造成本也比较大。

阶段二

后来我接手了这个问题,在这个基础上提出了一个新的问题: 那为啥只有部分生僻字会出现这种情况呢?

初步判断,这些加解密失败的生僻字的原字符编码比较特殊,可能国密加密库的实现对其支持不到位

查阅了一些关于文字编码的资料后,尤其是阮一峰老师的《Unicode与JavaScript详解》后,豁然开朗

  • 尝试针对这些加解密失败的生僻字进行 Unicode 还原,发现这些生僻字都是 4 字节的,而那些 2 字节的生僻字通过加解密后可以正常显示
  • 尝试更换国密加密库进行尝试,发现可以进行正常的加解密显示

原本打算直接更换三方的国密库,奈何金融系统对源码要求高,所以还是需要使用自研的这套sm4加密库。

不过已经定位到是因为 4 字节生僻字导致的加密后乱码的原因,直接对接研发中心负责加密库的团队申请源码,发现果然是不同字节字符加密处理时,唯独没有支持 4 字节的字符转换,导致加解密异常了。

更换新的 sm4 加密库后,问题终于得到解决!

后记

这个问题,总的来说也算是公司自研加解密库的一个缺陷,生僻字的字符加密没有考虑全面,不过一步一步抽丝剥茧下来分析问题的过程,还是想记录下来以作分享,希望大家分析一些问题时可以有一些启发和参考。

相关推荐
我命由我1234512 小时前
CesiumJS 笔记 - 获取容器中心点、Cartesian3 clone 方法、修改 Cartesian3 对象的高度
前端·javascript·css·前端框架·html·html5·js
抱抱宝13 小时前
Agent-study项目教程(03):手写 Mini-ReAct Agent(不依赖框架)
javascript·人工智能·gpt·react.js·prompt·agent
用户9385156350714 小时前
Next.js 笔记系统(二):Redis 数据服务与侧边栏组件拆分实战
javascript·全栈
Heo17 小时前
大厂前端调试不能只会debugger
前端·javascript·面试
windliang18 小时前
Claude Code 源码分析(十二):错误处理与自动恢复:让 Agent 稳定运行
前端·javascript·面试
默_笙19 小时前
🛬 前端路由的"高级玩法":懒加载、404、鉴权路由,一个都不能少(下篇)
前端·javascript
sunly_19 小时前
TypeScript:3、类型声明与类型推断
javascript·ubuntu·typescript
奥莱维20 小时前
【无标题】
java·前端·javascript
黄金决明子21 小时前
浏览器Window底层操作全解
前端·javascript
AI视觉网奇1 天前
cannot import name ‘model_urls‘ from ‘torchvision.models.resnet‘
linux·前端·javascript