何为认证

计算机本身无法判断坐在显示器前的使用者的身份,为了弄清究竟是谁在访问服务器,就得让对方的客户端自报家门。假设正在访问服务器的对方声称自己是 ueno , 但身份是否属实却无法认证。为此,需要核对“登录者本人才知道的信息”、“登录者本人才会有的信息”。通常核对以下信息:

  • 密码:只有本人才知道的字符串信息
  • 动态令牌:仅限本人持有的设备内显示的一次性密码
  • 数字证书:仅限本人(终端)持有的信息
  • 生物认证:指纹和虹膜等本人的生理信息
  • IC 卡等:仅限本人持有的信息

    HTTP 使用的认证方式

  • BASIC 认证(基本认证)

  • DIGEST 认证(摘要认证)
  • SSL 客户端认证
  • FormBase 认证(基于表单认证)

    BASIC 认证

    image.png

  • 步骤 1 :请求需认证的资源时,服务器响应 401 Authorization Required 状态码

  • 步骤 2 :接收到 401 状态码的客户端将用户 ID 及密码用冒号(:)连接后,再经过 Base64 编码处理后写入首部字段 Authorization 后,发起请求
  • 步骤 3 :接收到首部字段 Authorization 请求的服务器验证其中包含的信息。认证通过则响应 200 状态码

    BASIC 认证虽然采用 Base64 编码方式用户信息,但并不是加密处理。窃听者不需要任何信息即可对其解码,它的安全性很低,所以这种方式并不常用。

DIGETST 认证

DIGEST 认证是用来弥补 BASIC 认证存在的弱点,同样使用质询/响应的方式,但是它不会直接发送明文密码
image.png

  • 步骤 1 :请求需认证的资源时,服务器响应 401 Authorization Required 状态码,同时响应 WWW-Authenticate 字段,字段内包含认证所需的临时质询码(随机字符串 nonce)
  • 步骤 2 :接收到 401 状态码的客户端将 username、realm、nonce、uri和response 进行组装后写入 Authorization 字段后,发起请求
  • 步骤 3 :接收到首部字段 Authorization 请求的服务器验证其中包含的信息。认证通过则响应 200 状态码

    DIGEST 认证虽然提供来高于 BASIC 认证的安全登记,但是和 HTTPS 的客户端认证相比仍旧很弱。它提供防止密码被窃听的保护机制,但并不存防止用户伪装的保护机制,这种方式也不常用。

SSL 客户端认证

SSL 客户端认证是借由 HTTPS 的客户端证书完成认证的方式。凭借客户端证书认证,服务器可确认访问是否来自已登录的客户端。

SSL 客户端认证的认证步骤

  • 步骤 1 :请求需认证的资源时,服务器会发送 Certificate Request 报文,要求客户端提供客户端证书
  • 步骤 2 :客户端将用户选择发送的客户端证书以 Client Certificate 报文方式发送给服务器
  • 步骤 3 :接收到客户端证书请求的服务器验证通过后拿到客户端的公开密码,然后开始 HTTPS 加密通信

    SSL 客户端认证采用双因素认证

    在多数情况下,SSL 客户端认证不会仅依靠证书完成认证,一般会和基于表单认证组合形成双因素认证。如果银行金融类系统的密钥盘以及一些企业内部系统都使用这种双认证。

    基于表单认证

    客户端向服务器上的 Web 应用程序发送登录信息(Credential),按登录信息的验证结果来决定认证是否成功。

    认证多半基于表单认证

    由于使用上的便利性及安全性问题,HTTP 协议标准提供的 BASIC 认证和 DIGEST 认证几乎不怎么使用。另外,由于 SSL 客户端认证的额外证书费用开销等问题,所以多用 Web 应用程序各自实现基于表单的认证方式。

    Session 管理及 Cookie 应用

    基于表单认证本身是通过服务器端的 Web 应用,将客户端发送过来的用户 ID 和密码与之前登录过的信息做匹配来进行认证的。但鉴于 HTTP 是无状态信息,无法利用协议保存已认证成功的用户状态。因此,引入 Cookie 来管理 Session,以弥补 HTTP 协议中不存在的状态管理功能。
    image.png

  • 步骤 1 :客户端将用户 ID 和密码等登录信息放入报文的实体部分,通常以 POST 方法发起请求至服务器

  • 步骤 2 :服务器验证通过后把用户的认证状态与 Session ID 绑定后记录在服务器端
    • 向客户端返回响应时,利用首部字段 Set-Cookie 写入 Session ID。并且给 Cookie 设置 httponly 属性
  • 步骤 3 :客户端接收到从服务器端发来的 Session ID 后,将其作为 Cookie 保存在本地。下次向服务器发送请求时,Session ID 跟随 Cookie 一起提交给服务器

    通常,不会直接明文存储密码。而先利用给密码加盐(Salt)的方式增加额外信息,再利用散列(hash)函数计算出散列值后再保存,这种加盐的方式更安全