当前位置: 首页 > 科技观察

如何保证APP与服务器通信的安全性?锁定你数据的4个小窍门

时间:2023-03-15 21:10:30 科技观察

最近,公司外包给别人的一个APP项目上线了。拿到源码后,代码质量真是一言难尽!刚才的用户比较少,但是没有问题。但是,随着用户数量的逐渐增多,问题也逐渐暴露出来。最严重的问题是我们APP与服务器的通信接口没有加密被人抓取,非法请求我们的接口获取数据。如何处理这个问题?领导把这项光荣而艰巨的任务交给了我。我只好硬着头皮去了。经过几天的摸索,我终于得出了一套APP与服务器之间还算安全的通信方式。机制。1、防非法调用——身份认证身份认证就是只有合法授权的用户才能调用我们的接口。这里我们使用Token认证机制。APP与服务器的整个通信过程如下:用户首先需要输入账号和密码进行登录;APP使用用户输入的账号和密码请求服务器登录界面;服务器对账号和密码进行验证,验证成功返回一个唯一的Token作为用户的身份证明;APP缓存Token,同时登录成功;用户使用APP浏览数据,APP每次向服务器请求数据时都要带上缓存的Token;验证成功则正常返回数据,验证失败则直接返回错误。(1)Token校验机制解决什么问题?想象一个场景,我们检测到API接口被恶意调用,因为所有的接口都必须使用Token来调用。根据Token我们可以快速查询对应的用户,所以Token验证机制可以帮助我们快速判断调用者的身份。当发现恶意来电时,我们可以通过Token确认来电者身份后,采取token失效、账号封禁等措施,防止恶意来电继续进行。(2)Token校验机制能否防止抓包?Token验证机制并不能防止APP被抓取,因为Token也有泄露的风险。恶意调用者只需要携带Token请求我们的API接口,仍然可以获取到数据。因为APP和服务端是明文通信,一抓包就可以看到请求参数和返回数据,所以为了防止抓包,我们必须对数据进行加密。2、防抢包-数据加密数据加密的过程就是将明文传输的原始数据按照一定的加密算法进行加密,使其成为不可读、无意义的密文。加密算法大致可以分为对称加密、非对称加密、哈希算法等几种方式,后面我们的解决方案中都会涉及到。(1)对称加密对称加密是一种可逆的加密算法,这里的“对称”是指加密过程和解密过程使用相同的密钥。常见的对称加密算法有DES、3DES、AES、IDEA等。使用对称加密算法的一个完整的加解密过程如下:APP与服务端事先约定好一个对称加密密钥,并分别保存;APP使用密钥对明文参数进行加密,然后将密文发送给服务器;服务器收到密文后,使用相同的密钥对密文进行解密,得到明文;服务器还需要对数据进行加密后再返回给APP;对称加密算法的特点:对称加密算法的特点是算法公开,计算量小,加密速度快,加密效率高。对称加密算法的安全性取决于密钥,任何人得到密钥都可以对数据进行加密和解密。由于参与通信的双方都需要持有密钥,如果任何一方的密钥泄露,双方的通信就会不安全,所以如何安全地保存和传递密钥是使用对称时最重要的问题加密。(2)非对称加密顾名思义,非对称加密是指在加密过程和解密过程中使用不同的密钥。非对称加密算法需要一对密钥(公钥和私钥)。公钥用于加密数据,私钥用于解密数据。常见的非对称加密算法有RSA、ECC、ElGamal等。非对称加密的加解密过程如下:APP和服务端生成一对密钥对(公钥和私钥),公钥交给对方,私钥自己保存;APP使用服务器的公钥对数据进行加密配对,然后将加密后的密文发送给服务器;服务器收到密文后,使用自己的私钥对密文进行解密,得到明文数据;服务器返回的数据也需要使用APP的公钥加密数据;非对称加密算法的特点:非对称加密算法使用公钥加密,私钥解密。私钥不需要公开传输,安全性高。同时私钥可以对数据进行签名,公钥可以用来验证签名,可以解决中间人攻击和信息篡改等问题。由于加解密过程使用不同的密钥,对大量数据进行加解密的速度比较慢。通常,非对称加密算法只适用于少量数据的加密和解密。对称加密算法运算速度快但安全性不足,非对称加密算法安全性高但运算速度慢,那么我们的数据加密方案应该采用哪种加密算法呢?由于这两种加密算法各有优缺点,我们可以将两者结合起来:使用对称加密算法对数据进行加解密,以保证运算速度,使用非对称加密算法对对称加密算法的密钥进行加密,从而取考虑到密钥的安全性。3、抗重放攻击——时间戳+随机字符串数据加密后通信。虽然抓包后看不到明文数据,但这并不妨碍恶意者发起重放攻击。拦截请求后,只需将请求原样发送到服务器即可发起重放攻击。如果接口中存在一些性能密集型逻辑,比如数据库查询,那么在短时间内发起大量的重放攻击,会直接导致服务器崩溃。如何解决这个问题呢?原因其实很简单。我们只需要保证请求只能被正确处理一次即可。这里我们采用时间戳+随机字符串的方案。(1)时间戳我们在发送的数据上加上当前的时间戳。服务器收到请求的数据后,首先取出时间戳,与服务器当前时间进行比较。如果两者相差超过一定的时间(比如5分钟),那么我们就认为这个请求超时了,就拒绝执行或者返回错误。(2)随机字符串我们在发送的数据中加入一个随机生成的字符串。服务器收到请求数据后,首先在缓存中查找字符串。如果在缓存中找到,则认为是重复请求。拒绝处理,否则将字符串加入缓存,继续执行正确的逻辑。在请求中加入时间戳和随机串后,服务端收到请求后会先对时间戳和随机串进行校验,校验通过后才会执行正常的业务处理逻辑。4.防篡改——数字签名为了防止重放攻击,我们在数据中加入了时间戳和随机字符串,但是别人拦截我们的请求后也可以篡改时间戳和随机字符串。服务器应该如何区分这种情况呢?为了防止数据在传输过程中被篡改,我们引入了数字签名机制。(1)信息摘要算法信息摘要算法(或哈希算法)是一种不可逆算法。任意长度的明文数据,经过信息摘要算法计算后,可以计算出一个固定长度的值(签名)。常见的信息摘要算法有MD5、SHA-1等。详细签名过程:将数据密文、时间戳、随机串和私有盐值共同使用,通过信息摘要算法计算出签名值;APP将数据密文、时间戳、随机串和签名值一并发送给Server;服务器收到数据后,对数据的密文、时间戳、随机串和salt值进行相同的信息摘要算法计算,将计算出的签名与数据中的签名进行比较,证明签名一致。篡改;(2)为什么要在信息摘要计算中“加盐”?比如123的签名值经过MD5计算后就是abc,那么就会有123->abc这样的对应关系,看到签名值abc就可以发现原来的值是123。如果有人收集并保存足够多的这些对应关系,就有可能从带符号的值中推导出原始值。这时候加盐操作就派上用场了。首先,我们生成一个加盐值qwe。这个加盐值qwe不会在网络上传播,只有通信双方知道。我们不直接计算123的签名值,我们在123上附加salt值得到123qwe,然后对123qwe进行MD5计算得到不同的签名值def。所以即使原值相同,只要salt值不同,最终的签名值也会不同,所以不能从签名值推导出原值。5.完整的Java解决方案因为本人主要从事Java开发,所以用Java语言实现了一套加解密方案。对称加密采用AES算法,非对称加密采用RSA算法,信息摘要算法采用MD5算法。完整的代码执行过程:下面分步详细介绍:准备工作:APP和服务端各自生成一对RSA密钥对(公钥和私钥),公钥给对方,私钥是私密保存的;APP发送加密数据流:生成随机AES算法密钥;使用服务器的RSA公钥对AES密钥明文进行加密,得到AES密钥密文;对参数明文进行AES加密,得到参数密文;生成当前请求时间的时间戳;为此请求生成一个随机字符串;计算参数密文、时间戳、随机字符串和AES密钥密文的MD5值,得到md5值;使用APP自带的RSA私钥对md5值进行签名得到签名值;将参数密文、时间戳、随机串、AES密钥密文和签名值发送给服务器;服务器解密数据过程:检查时间戳与服务器当前时间的差值是否在合理范围内,如果超过则认为请求超时;检查随机字符串是否已经在缓存中,如果已经在缓存中,说明该请求是重复请求,否则将该字符串加入缓存;从接收到的数据中取出参数密文,时间戳,随机字符串,AES密钥密文计算md5值;使用APP的RSA公钥对计算出的md5值和请求数据中的签名值进行校验,如果签名校验通过,则说明请求数据没有被篡改;服务器使用自己的RSA私钥解密AES密钥密文得到AES密钥明文;使用AES密钥明文对参数密文进行AES解密得到参数明文;获取到参数明文后,进行正常的业务处理逻辑;服务器数据需要经过同样的加密操作才能返回给APP;6.综上所述,APP与服务器必须使用HTTPS协议进行通信,然后使用RAS+AES混合加密算法和数字签名机制。相信这套方案在大多数情况下都能保证通信和数据的安全。当然,也不排除APP被人破解的可能。在这种情况下,任何加密机制都是无用的。但是也不能说我们的加密机制就没有用,只是需要在一定程度上增加破解我们APP的成本。这个原理其实和门锁是一样的。市场上的大部分门锁,只要有时间,都可以用开锁器打开。你能说门锁没有意义吗?