在金融领域,cfca(中国金融认证中心)是必然会接触的,使用了cfca键盘,提供了客户端到服务端的加解密功能。

在某个需求时遇到一个cfca加解密失败。

功能伪代码如下, 先接口获取开关配置,再决定展示UI。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<template>
<div>
<div v-if="enable">
// other code
// ...
<cfca />
</div>
<div v-else>
// ...
</div>
</div>
</template>
<script>
export default {
data() {
return {enable:false}
},
async created() {
const enable = await getConfig('enable');
this.enable = enable;
}
}
</script>

提交请求后,提示解密失败。

  1. 回顾下这个功能,就加解密功能而言,cfca是第三方服务,而且其他页面使用中没问题,所以原因不在cfca。
    而加解密功能,都是cfca提供的,客户端按照流程提供密文和密钥即可。

  2. 解密失败,则说明提供的密钥和进行加密的密钥不一致。

  3. 如果,使用者密钥存储在服务端,那跟前端无关,就不会在这个功能点报错。
    所以,推测密钥存储在客户端。

  4. cfca提供的是一个iife的sdk,并进行了组件级的封装。 完成了键盘组件的初始化,交互与加密传输。

  5. 加密方式对不上,那么加密初始化存在问题。js存储方式无非几种。1. 内存中,如挂载在全局的window下面; 2. 缓存,localStorage sessionStorage 3. 页面DOM中的data tag

  6. 如果是跟页面无关的存储,如window storage, 那么密钥应该是一致的,不存在变更。 所以,加密方式与密钥很可能是存储到DOM中。 查看组件的初始化操作,发现,组件进行了初始化请求密钥和随机数之后,
    初始化了键盘,在之后的键盘操作中,会对键盘点击的数据进行加密,会得到加密的数据结果。

  7. 而 v-if 指令值为false时,是不会渲染DOM的,那么初始化键盘将找不到目标,失败。当v-if为true,渲染出键盘时,内部加密的随机数已经不存在了。

所以,我们将v-if 替换为 v-show, 保证键盘组件一直存在,解决了问题。