# 可信环境判断

自接口加上SSL之后,数据传输安全的问题是解决了。整理一下我们用到了哪些算法以及使用场景:

  1. 防篡改的时候,我们用到了RSA或SM2做加签及验签操作,也即客户端及服务端各持一对公私钥,客户端请求服务端时,使用客户端的私钥签名,服务端用客户端的公钥验签。服务端响应数据时使用服务端的私钥签名,客户端用服务端的公钥验签。
  2. 防窃听时,如果开启双向认证的时,与防篡改类似,客户端与服务端各持一对RSA公私钥。

这里先提出一个问题,就是客户端或服务端,如何判断对方是可信的,而不是伪造的。

# 客户端判服务端

一般来说,服务端被攻击的可能性相当来说,比较低,这时服务端持有的私钥一般情况下是很难被第三方知晓的。所以无论是防篡改的私钥还是防窃听的私钥,服务端一般可以认为是可信的。

那么客户端只要能用服务端的公钥正常验签通过,SSL建立时服务端返回的证书是合法的即可认为服务端是可信的。

# 服务端判客户端

服务端判客户端是否可信,我个人觉得比较难,因为客户端是大众可以轻易接触到的,那么客户端持有的私钥就很难保证不被窃取。这也就是为什么早期一些网银需要使用一个UKey,UKey里面一般都会写入证书或签名用的私钥,把UKey当作一个黑盒子,第三方要破解客户端可能相对容易,破解UKey就会难很多。

# 有状态和无状态

接口我们可以根据用户是否已经登录或未登录来划分有状态和无状态类型,针对有状态的接口,我们可以获取到用户的唯一标识之类的。

前面讲到可信环境的判断,主要是卡在服务端判客户端是否可信上,我们先看看有状态的可信好不好判断?

# 有状态可信判断

有状态的可信判断是比较好做的,来看看我一般的做法:

  1. 用户登录前,随机生成一对公私钥
  2. 用户首次登录一台设备时,要求验证短信验证码。
  3. 登录时将短信验证码、随机生成的公钥、用户名和密码,传至服务端。
  4. 服务端验证短信验证码来判断客户端的可信。
  5. 验证通过后,后续所有有状态接口,比如获取用户资料之类的,客户端使用步骤1生成的私钥签名,服务端用步骤3收到的客户端公钥验签。

这时窃听者是没办法窃听到用户的短信验证码的,所以他没办法伪装。

再加强一点,还可以在用户首次登录新设备时,进行活体检测及人脸验证。这基本就断了窃听者伪装的路了。

疑问

可能有些同学会有一个疑问,就是假设窃听者能伪装SSL,拦截到发送至服务端的短信验证码,不也可以伪装吗。 这当然就要求,针对敏感数据或密钥数据,在传输时,我们要做处理,后续章节会讲,可看后续敏感数据及密钥传输安全。

# 无状态可信判断

那就剩下无状态的可信判断了,也就是说服务端暴露在攻击者面前的,只剩下一些像发送短信验证码、登录、获取服务器时间、获取图形验证码之类的无状态接口了,这些是容易被攻击和窃听的了。

针对无状态接口的防护呢,依然是加签及SSL,那么重心就放在了如何在客户端安全的存储无状态接口下的私钥的安全。

后续的密钥传输安全章节会着重的讲一些常规手段。