本章节主要讲,密钥在传输过程中,如何保障其安全性。

密钥的传输安全,我们可以利用非对称加解密的特性来做,即公钥加密后,只能用私钥来解密,公钥是可以公开出去的。所以在密钥传输上,我们只要使用对方的公钥将密钥加密后,传给对方就不用担心被攻击者拦截并破获。

但是这也不是绝对的,因为客户端软件是公开的,攻击者可通过反编译或反汇编手段,获取到客户端的私钥,此时客户端是非可信的。所以密钥的传输呢,还是要分场景来分析。

# 可信环境

可信环境下,密钥传输还是比较好做的,客户端将密钥传输给服务端,只需要用服务端的公钥加密后,再传给服务端即可,服务端传给客户端同理。

因为是可信环境,所以不用担心自己手上持有的对方公钥是错误的,传输过程中呢,攻击者也没有相应的私钥,是无法解密出来的。

# 非可信环境

通过前面这些章节呢,我们知道目前暂时只有一种情况是非可信环境(忽略服务端被攻破情况),即客户端在无状态下时,是非可信的。

那么在这种情况下,服务端是没办法确定,当前它持有的客户端公钥是不是可信的,也就是说服务端传输密钥或其它数据时,使用客户端公钥加密响应给客户端,它也不知道会不会被别人拦截并破获。

那有没有办法去解决或尽量规避这个问题呢,目前我想到三种办法:

  1. 使用硬件,将客户端私钥存储在硬件中(如UKey、加密狗),那么在非可信环境下传输数据或密钥时,由硬件加密后再传输。
  2. 将私钥使用复杂的加密算法加密后,打散存储在C++中,运行时再还原回来。
  3. 客户端不存储私钥,要用时,先使用密钥协商算法(如SM2的密钥协商),协商好一个过程密钥后,服务端使用过程密钥将私钥下发给客户端,也即由服务端帮客户端代管私钥。

第2种办法没有第1种安全,只能增加攻击者破获的难度。第3种方法呢,比第2种复杂,密钥协商呢,也涉及到了存储一对私钥,这对私钥是用来做密钥协商的,此时也还是要用第2种方法来保存用来做密钥协商的私钥。

所以最终非可信环境下,要想好好保存私钥,就要发挥想像,增加破解难度,比如采用一些静态白盒算法+SO库加壳,定制密钥协商算法,SO防静态分析等。就是使用一些非常规算法和手段,来隐藏私钥。