zoukankan      html  css  js  c++  java
  • API网络数据安全

    前言

    个推作为国内第三方推送市场的早期进入者,专注于为开发者提供高效稳定的服务,在保证稳定的情况下,我们的网络数据交互也达到了一个很高的级别,今天给大家分享的是网络数据安全的常用方法

    简介

    TCP/IP作为互联网使用的标准协议集,在设计之初就是建立在接入主机互相信任的前提下,缺乏对安全方面的考虑,并且为了保证网络的开放性,TCP/IP协议的内容是完全公开的。因此,只使用TCP/IP协议在互联网上传输的数据,实际上都是不安全的。
    在SDK开发场景下,通常会在API设计时加入一些网络安全的措施,这里主要从数据防泄露、内容防篡改、身份放伪装、请求防重放几个方面分析如何保证API网络数据安全。

    数据防泄露

    为了保证数据的机密性,一般会对数据做加密操作,这样即便数据在传输时被抓取,也需要解密才能获取真实数据。而要加密就需要用到加密算法,下面按两种粗略的分类介绍下不同加密算法的特点,如何选择合适的加密算法,以及加密算法使用的密钥该如何管理。

    公开加密与非公开加密算法

    按照算法是否公开的特点,加密算法可分为公开算法和非公开算法。

    • 公开加密算法
      加密算法公开,密码的安全基于密钥的安全
    • 非公开加密算法
      加密算法不公开,只有开发人员知道,密码的安全性基于加密算法的安全;

    建议使用公开加密算法。公开算法因为受全世界的密码学者研究,经受了很大的考验,加密强度有保障。而非公开算法除了作者之外基本上没人看过,加密的强度没有保障。一旦加密方式泄露,非公开加密算法需要做修改算法这种复杂操作来补救,而公开加密算法本来就是公开的,只要密钥不泄露就是安全的,即使密钥泄露也只需更换密钥的简单操作即可。

    对称加密与非对称加密

    按照密钥的特点,公开加密算法又可以分为对称算法和非对称算法

    • 对称加密算法
      只有一个密钥,简称私钥,加密和解密使用同一个密钥
      特点:计算量小,速度快,密钥交换复杂
      常见的对称加密算法:DES,AES,TDEA 等
    • 非对称加密算法
      有一对密钥,可公开的公钥与补课公开的密钥,用其中一个密钥对数据进行加密后,只有用对应的另一个密钥才能解密。
      特点:计算量大,速度较慢,支持数字签名,密钥交换简单。
      常见的非对称加密算法:RSA,Elgamal,Rabin,ECC,D-H。

    实际使用中通常采用非对称加密算法管理对称算法的密钥,然后用对称加密算法加密数据,这样我们就集成了两类加密算法的优点,既实现了加密速度快的优点,又实现了安全方便管理密钥的优点。

    内容防篡改

    数据在网络的传输过程中,很有可能被拦截并对内容进行篡改,对于这种情况,通常在传输内容中增加特定哈希算法生成的hash值,用来校验内容是否被篡改过,以保证数据的完整性。

    常见的哈希函数有 md4,md5,sha-1等,通常会在请求或响应的内容体中增加一个校验参数sign,为了增加破解的难度,校验参数一般不会只是简单地对内容进行哈希运算生成,而是使用一种被称为加盐哈希的操作。
    具体做法可以是在内容中增加一些别的参数,比如SDK开发场景中通常会由开发者平台生成一个appSecretKey,可以把这个key放入请求内容中的特定位置,然后在再用哈希函数生成hash值,这之后还可以根据需要多进行几次哈希操作,比如先用md5做哈希计算生成hash值,再把这个值当成盐放到下次的sha-1计算中等等。
    接收端在接收到内容时使用同样的哈希操作计算sign值,并将两个sign值进行比对,如果不一样则说明内容被篡改过了。

    身份伪装

    在网络通信中,通信双方的身份验证也是网络安全中非常重要的一环,它既可以保证网络通信双方的身份,又可以防止通过网络完成交易时,交易方宣称交易没发生过的抵赖行为,保证了通信双方身份的可鉴别和通信过程的不可抵赖。在SDK开发中,由于api接口是对外公开的,因此对客户端的身份校验一般不会很严格,主要是对服务端的身份验证。

    Token 身份校验

    服务端为了防止接口的未授权调用,通常会生成一个用于标识客户端身份的token,客户端在调用接口时在请求头中添加token,服务端检查token是否有效,如果有效则说明客户端的身份可靠,可以返回响应数据,通常会对token设置一个有效期以防止token泄露后的长期非法调用。如果对客户端身份验证要求较严,可以将token的生成与apk的签名文件关联起来,如果不是使用指定签名的客户端,则无法通过校验。

    数字签名

    服务端一般通过数字签名的方式支持身份验证,数字签名是非对称加密算法的另一种用法,用私钥加密,用公钥解密,它可以提供和现实中亲笔签名相似的效果,在技术上和法律上都有保证。
    数字签名与验证过程:

    • 发送方用哈希函数从报文文本中生成一个hash值;
    • 发送方用自己的私钥对这个hash值进行加密形成自己的数字签名;
    • 发送方将数字签名和报文一起发送给接收方;
    • 接收方收到报文后,用同样的哈希函数从原始报文中计算出hash值;
    • 接收方再用发送方的公钥来对报文附加的数字签名进行解密得出另一个hash值;
    • 如果两个hash值相同,那么接收方就能确认该数字签名是发送方的;

    请求重放

    即使传输的数据是经过加密的,窃听者无法得到数据的准确定义,但从请求的地址分析出这些数据的作用之后,可以通过原封不动地多次发送这条请求进行攻击,就拿最简单的数据入库操作,如果API接口没有做对应的安全防护,将可能造成多次入库的严重后果。

    为了避免这种情况,通常会在请求中增加一些用于校验的参数,比如时间戳、随机数、流水号等等,下面简单介绍一下这几种方式的特点,以及常用方案。

    加时间戳

    在请求中增加一个时间戳,服务端将时间戳跟当前时间对比,如果时间差大于一定值(比如1分钟),则可以认为该请求失效。这种方式无法防止在指定时间差内的重放攻击,比如时间差是1分钟的话,那么只需要在1分钟内完成重放攻击即可。

    加随机数

    在请求中增加一个随机数,服务端检查缓存中是否有相同的随机数,如果有则认为是无效请求,如果没有则将其加入缓存。这种方式的问题在于,服务端不可能缓存所有请求的随机数,只能缓存一部分,如果重放攻击内包含的随机数刚好被清除了,则依然能被攻击。

    加流水号

    在请求中增加一个递增的流水号,服务端如果收到的流水号不是连续递增的,就认为是无效请求。这种方式的缺点在于流水号的变化太过单调了,很容易就能被识别出来并做对应的修改。

    时间戳+随机数

    常用的方案是把时间戳和随机数配合使用,给每次请求都增加一个当前时间的时间戳timestamp,和一个随机数nonce。服务端收到请求时,先检查时间戳是否超时,如果超时则认为是无效请求,如果没超时再检查缓存中是否有相同的nonce,如果有则认为是无效请求,如果没有则将其加入缓存,服务端只需要缓存超时时间内的nonce记录即可。

    使用 https

    前面介绍的这些网络安全的相关手段,如果实际开发中要严格按照上面的标准实现的话,还是需要花费一些时间的,那么有没有一种快速简单的方式来实现上面提到的那些功能呢,答案是有的,那就是直接使用Https。
    Https实际上是由Http+SSL组成,SSL能够提供数据加密、身份验证功能,只需再加上简单的防篡改和防重放功能即可满足上面的数据防泄密、内容防篡改、身份防伪装、请求防重放四个要求。

    SSL/TLS

    SSL是Netscape公司研发的用于保障数据在互联网上安全传输的协议,SSL在更新到3.0时,IETF(互联网工程任务组)对SSL3.0进行了标准化,添加了少数机制,并将其更名为TLS。
    SSL/TLS建立安全通信的过程大概可以分为三步:

    1. 对等协商支持的密钥算法;
    2. 基于公钥加密的对称密钥交换,基于证书的身份认证;
    3. 基于对称加密的数据传输保密

    数字证书

    使用Https时,需要用到数字证书,数字证书的原理其实还是前面说到的数字签名,一般数字证书都是由CA机构用私钥签发的,当然也有企业自己用私钥签发的数字证书,只是这种证书默认是不被信任的,使用数字证书可以有效地防止参数篡改和身份伪装。
    数字证书的大致生成过程如下图:

    步骤:

    1. 根据证书内容(比如公司名,公司税号等)使用哈希算法生成一个证书摘要
    2. 拿这个哈希过的摘要进行 RAS 加密。
    3. 加密的数据又存放到证书中

    数字证书的验证过程大致如下图:

    步骤:

    1. 在建立链接之前,下载证书进行校验
    2. 对证书内容进行哈希等到数字摘要 H1
    3. 使用密钥解密数字签名得到数组摘要 H2
    4. 如果 H1=H2 则认为校验通过

    在SDK开发中,使用CA颁发颁发的证书和使用自生成的证书差别并不大,主要区别在于,如果使用CA颁发的证书,只需在SDK中使用系统自带的信任证书库验证即可(系统默认内置CA机构根证书),如果使用自生成的证书,则需要在SDK中导入证书或公钥用于证书验证过程。

    单向与双向认证

    • 单向验证
      客户端需要验证服务器的身份,服务端不需要验证客户端身份。

    • 双向验证
      客户端需要验证服务器身份,服务端也需要验证客户端身份。
      使用单向验证还是双向验证,通常是由服务端提供的服务决定的。一般情况下服务器是对所有客户端开放的,所以默认的配置是单向验证。如果要限制访问的客户端,则需要在服务端开启双向验证。

    书籍推荐

    《TCP-IP 详解 卷一》,《图解 Http》

    总结

    安全是个大课题,这篇文章仅是基于网络安全这个很小的点进行拓展。后续还会出 设备安全,数据安全,代码安全等文章,希望大家多多关照。

  • 相关阅读:
    webservice测试工具
    Spring+CXF整合来管理webservice(服务器启动发布webservice)
    BAT常用命令
    【shell入门】Shell用法
    【shell】Shell命令合集(0)
    挨踢江湖之十二
    shell一些笔记
    在优化SQL语句中使用虚拟索引
    Jenkins Maven打包出错异常的解决方法
    [置顶] ios 360度旋转效果demo
  • 原文地址:https://www.cnblogs.com/evakang/p/12059429.html
Copyright © 2011-2022 走看看