由开发小程序信息解密 API 思考到的

2017-10-03  本文已影响26人  苏尚君

最近开发了一个小功能,用于从微信返回的数据中解密获得信息。流程上不太复杂,但因为一开始设计和后续debug过程中出现了一些问题,因此记录一下,以为后人鉴。

按照我的设计,【API】的工作流程是:

  1. 从微信那里获取 密文(以下称 encryptedData)、密钥(以下称 iv)、会话凭证(以下称 session_key
  2. 后使用后两者来解开密文,获取到需要的信息
  3. 根据获取到的信息进行后续处理

这里要解释一下【解密】的工作流程:

问题就出在 code->session_key 这里:

找理来说这好像也没啥大问题:无非是进行了一次功能分离,让 decrypt 更「专注」了。这里还要继续展开上面的 【解密】工作流中:即获取到 ivsession_key 后,并不能直接用于解密,因为腾讯服务器给出的这两个字符串本身经过一次编码处理,我需要对腾讯返回的两样东西进行解码处理后,才能用于解密 encryptedData。坑就是出在这里了。

在第一次设计时,我的解密函数 decrypt 接口是:

def decrypt(encrypted_data, iv, code)

解密函数内部是用的类似下述语句:

# 在解密函数中用 code 去换取 session_key
session_key = base64.b64decode(get_session_key(code))
iv = base64.b64decode(iv)
encrypted_data = base64.b64decode(encrypted_data)
# 用 session_key, iv, encrypted_data解密……

这套语句是完全copy自腾讯官方给的解密样例 demo。设计完成后(即获取到号码,并将其成功写入了数据库),我开始写单元测试。写测试时我发现了上面所说的 decrypt 的接口不适合测试的问题,然后开始改 decrypt 的接口,改成了

def decrypt(encrypted_data, iv, session_key)

解密函数内部则改成了:

# 直接使用 session_key 去做解密工作,因此不在内部对得到的 session_key 进行处理
iv = base64.b64decode(iv)
encrypted_data = base64.b64decode(encrypted_data)
# 用 session_key, iv, encrypted_data解密……

注意到了第一行:我在修改函数的过程中,把这句 session_key = base64.b64decode(get_session_key(code)) 直接就删掉了——而正常工作过程中,应该是改成 session_key = base64.b64decode(session_key)。但我没有做此处理,于是导致直接用编码过的 session_key 去做解密工作,解密不出正常的内容,得到的东西一直提示不能用 utf-8 进行解码,而我一直都没注意到解码问题在解密函数中就出了错,而是一直在解密函数外部寻找问题,甚至在出错当天对照微信官方 demo 代码也没发现自己这个问题;直到第二天S哥看不下去了,自己也跑通了一遍官方 demo,我在他跑通的官方 demo 和自己的代码上对比了几次,才发现自己忘了 decode session_key 这一事实。

我现在把问题流程写出来,连我都觉得这东西怎么会犯错,本来就应该是用 session_key 去替代掉 get_session_key(code) 的位置。是不是我太粗心了?我觉得想到这一点还不够:「粗心」可能是指「没注意到某些细节」,而为什么我会没有注意到这个细节?是不是我的某些工作流程出了问题,我有没有可能通过改变工作流程来保证我下一次不会再出类似的错?和S、Q、W等人讨论后,我觉得以后可以尝试以下方法:

总结暂时就这些。不知道有没有其他小伙伴遇到过类似的坑,有的话你们是否还有其他思路,或者对上面提出的 3 种解决方案有什么想法?

上一篇 下一篇

猜你喜欢

热点阅读