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 加密库后,问题终于得到解决!

后记

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

相关推荐
意法半导体STM327 小时前
STM32 USBx Device HID standalone 移植示例 LAT1466
javascript·stm32·嵌入式硬件·device·hid·standalone·usbx
Miss Stone7 小时前
css练习
前端·javascript·css
Sailing8 小时前
前端拖拽,看似简单,其实处处是坑
前端·javascript·面试
带只拖鞋去流浪9 小时前
Vue.js响应式API
前端·javascript·vue.js
前端小灰狼9 小时前
Ant Design Vue Vue3 table 表头筛选重置不清空Bug
前端·javascript·vue.js·bug
前端付豪9 小时前
11、JavaScript 语法:到底要不要写分号?一文吃透 ASI 与坑点清单
前端·javascript
Copper peas9 小时前
Vue 中的 v-model 指令详解
前端·javascript·vue.js
lecepin9 小时前
AI Coding 资讯 2025-09-25
前端·javascript·后端
dreams_dream9 小时前
Vue树选择
javascript·vue.js·elementui
云枫晖9 小时前
手写Promise-静态方法reoslve和reject
前端·javascript