基于Android App 安全登录认证解决方案

近几年移动互联网的高速发展,智能手机的使用用户呈现爆炸性增长,手机终端上的App 种类繁多,大多数App 都需要与后台系统进行交互,交互的第一步需要进行登录认证,过于简单的认证方式可能被破解从而造成用户信息的泄露甚至威胁着用户的财产安全。为此基于Android 系统,对比现有几种常见的App 登录认证方式,并提出一种采用RSA 非对称加密和加入Token 时效机制的登录认证解决方案。在登录验证阶段采用RSA 非对称加密方式,App 端对服务器端返回的Token 信息加上时间戳,将处理后的Token 信息保存到本地,后面的每次请求都携带该Token 从而实现免登录的登录状态的保持。

1. 登录认证方式

   1.1 Web登录认证方式

目前常见的Web认证的方式主要有三种:

(1)HTTP Basic Auth。 这种方式就是每次请求服务器时都携带用户名和密码,优点是使用非常简单,缺点也非常明显,因为每次都需要携带用户名和密码,很有可能造成密码被截获。

(2)OAuth。一种开放的授权标准,允许第三方应用访问用户在某一个服务商服务器上存储的私密数据,其处理流程先是第三方应用通过App Key和App secret换取OAuth_Token进行授权(此时颜色有可能需要输入用户名和密码),授权完成后服务商页面会跳转到第三方应用同时返回Access Token,此后第三方应用就可以通过这个Access Token去服务商服务器中访问相应数据。

(3)Cookie Auth。Cookie认证机制就是浏览器在发起一次登录认证请求时,服务端验证通过后将会在产生一段Cookie信息并返回给浏览器,浏览器会将其保存到本地,以后的每次请求都会使用该    Cookie信息而不再进行登录验证。

1.2 App登录认证方式

    由于App客户端无法处理Cookie信息,因此App登录认证无法使用Web认证方式中的Cookie认证方式,为了登录状态的保持,一般会模拟Cookie认证方式,即在App端发起登录认证请求后,得到服务端验证成功的确认之后,App端一般会保存一些状态信息在本地,后面每次请求都是携带该状态信息,根据状态信息的不同,可以分为如下两种:

(1) 保存用户信息表中的某个唯一标识。App端发起登录请求,服务器端在验证成功之后一般会将该登录用户的信息返回给客户端,客户端此时可以将用户信息中的某个唯一标识字段给保存下来,如使用SharedPreference进行保存,后面每次发起网络请求时,先判断本地是否存在该字段,如果不存在说明用户没有进行登录认证,跳转到登录页;如果存在,则直接将这个字段携带进请求信息中,从而实现登录保持状态。这种方式优点是比较简单,缺点就是如果保存的字段容易被别人截获,缺乏安全性。

(2)保存Token信息。App中非常常用的一种登录认证方式,他的实现过程是,由App端发起登录请求,服务器端在验证成功后生成一份Token信息保存到用户表中并设置一定的时效,同时将此Token返回给App端,App端将此Token保存到本地,以后的每次发起请求都是用该Token。与前面一种方式相比,避免了用户表中信息的泄露,相对更加安全。其流程图如下:

这种方式相对于第一种来说更加安全,但还是存在着明显的安全漏洞,需要进行优化。本文将以这种方案为基础,提出一种更加安全的基于Android平台的App登录解决方案。这里我们把现有的这种方案成为Token认证机制,本文提出的方案成为改进的Token认证机制。

2. 改进的Token认证机制详细设计

上述Token认证机制也是存在着一些明显的安全漏洞,本文提出的改进的Token认证机制就是基于对原来Token认证机制中安全漏洞的优化。对于登录认证机制,我们可以把它分为登录验证,状态保持和登出三个阶段,改进的Token认证机制主要是在登录验证和状态保持阶段进行优化。

   2.1 登录验证优化

登录验证阶段是指App客户端向服务器端发起登录认证请求,并携带用户名和密码,服务器端收到请求后获取用户名和密码,并向数据库进行查询验证的阶段。由于这一阶段需要密码的传输,很多情况下可能都是明文或者简单的MD5加密后直接传输,一旦被黑客截获可能造成密码的泄露风险。因此这一阶段的优化就是加强密码加密功能,这里我们采用RSA非对称加密方式。

RSA是一种非对称加密,它是对称加密的一种加强版,使用对称加密的服务器端和客户端都使用同一种加密规则,因此在服务器端生成加密密钥之后需要传递给客户端,客户端也需要保存这个密钥,而传递密钥的过程和保存密钥在客户端后都有可能发生密钥的截获造成安全漏洞。而非对称加密方式会在服务器端生成两套密钥,生成的公钥是公开的并传给客户端,私钥保存在服务器端,客户端用公钥加密信息后传递到服务器端,服务器端再用私钥进行解密,因此只要私钥不泄露,通信就是安全的。

由上面的分析可以知道,要使用RSA加密方式先要让服务器生成公钥和私钥,并将公钥返回给客户端,因此,在图1 的登录验证阶段需要额外进行一次请求获取公钥(这个过程只需要一次,只要获得了公钥以后登录认证就不再需要该过程),其流程如图2所示。

根据上面的分析, 可以看到这一阶段最核心的是服务器端公钥和密钥的生成过程以及利用公钥加密和利用私钥解密的过程。其核心代码如下:

 /*** 初始化密钥** @return* @throws Exception*/public static Map<String, Object> initKey() throws Exception {KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance(KEY_ALGORITHM);keyPairGen.initialize(1024);KeyPair keyPair = keyPairGen.generateKeyPair();// 公钥RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();// 私钥RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();Map<String, Object> keyMap = new HashMap<String, Object>(2);keyMap.put(PUBLIC_KEY, publicKey);keyMap.put(PRIVATE_KEY, privateKey);return keyMap;}
 /*** 取得公钥** @param keyMap* @return* @throws Exception*/public static String getPublicKey(Map<String, Object> keyMap)throws Exception {Key key = (Key) keyMap.get(PUBLIC_KEY);return encryptBASE64(key.getEncoded());}
 /*** 取得私钥** @param keyMap* @return* @throws Exception*/public static String getPrivateKey(Map<String, Object> keyMap)throws Exception {Key key = (Key) keyMap.get(PRIVATE_KEY);return encryptBASE64(key.getEncoded());}
/*** 加密<br>* 用公钥加密** @param data* @param key* @return* @throws Exception*/public static byte[] encryptByPublicKey(byte[] data, String key)throws Exception {// 对公钥解密byte[] keyBytes = decryptBASE64(key);// 取得公钥X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);Key publicKey = keyFactory.generatePublic(x509KeySpec);// 对数据加密Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());cipher.init(Cipher.ENCRYPT_MODE, publicKey);return cipher.doFinal(data);}
/*** 解密<br>* 用私钥解密** @param data* @param key* @return* @throws Exception*/public static byte[] decryptByPrivateKey(byte[] data, String key)throws Exception {// 对密钥解密byte[] keyBytes = decryptBASE64(key);// 取得私钥PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);Key privateKey = keyFactory.generatePrivate(pkcs8KeySpec);// 对数据解密Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());cipher.init(Cipher.DECRYPT_MODE, privateKey);return cipher.doFinal(data);}


      2.2 状态保持优化

App 客户端在上一步登录验证阶段会得到服务器返回的Token 信息,并将该Token 保存到本地,以后的每次请求都直接携带该Token 而不是再次使用用户名和密码进行验证,这一阶段称为状态保持或登录保持阶段。前面介绍的Token 认证机制中的Token 会一直保存在App 客户端本地直至用户主动点击退出按钮,如果该Token 被截获,截获者同样可以使用该Token直接访问服务器中的敏感数据。针对Token 这一长时间保存的特点,我们的优化就是为这个Token 设置一个生效时效,具体来说就是在从服务器获得该Token后,在保存的时候在Token 后加上一个当前的时间戳,后面每次发起网络请求时,先取出该Token 后面的时间戳判断有没有超过生效时间,如果没有则将处理后的Token 放入到请求信息中,如果超时了,则重新进行登录认证过程。这种优化过程是以牺牲了一点用户体验为代价。其流程图如下:

本文章详细探讨了常见的Web 登录认证方式和App登录认证方式, 对现在比较常用的App 登录认证方式Token 认证机制的安全漏洞进行了讨论,在这个基础上提出了改进的Token 认证登录机制, 通过采用RSA 非对称加密优化登录验证阶段, 使用Token 时效机制优化状态保持阶段, 该优化方案在实际生产中得到了检验。同时,该方案还有进一步优化的空间,例如在优化状态保持阶段时采用的是Token 时效机制, 但这样牺牲了App 的使用体验, 因此在以后的研究中可以针对这一阶段做进一步的优化过程。

Android App 安全登录认证解决方案相关推荐

  1. APP的登录认证与安全

    一.登录机制 粗略地分析, 登录机制主要分为登录验证.登录保持.登出三个部分.登录验证是指客户端提供用户名和密码,向服务器提出登录请求,服务器判断客户端是否可以登录并向客户端确认. 登录认保持是指客户 ...

  2. android app 自动登录,Android APP首次登录和之后自动登录流程

    Android APP首次登录和之后自动登录流程 Android APP首次登录和之后自动登录流程 App登陆保存数据流程 App因为要实现自动登陆功能,所以必然要保存一些凭据,所以比较复杂. App ...

  3. APP风控SDK之Android APP防作弊SDK解决方案

     推荐阅读 ​Android APP防作弊SDK解决方案 APP防代理抓包 APP防Fiddler抓包 APP防Burp Suite抓包 移动安全和Web安全 kali渗透测试环境搭建 Web安全|d ...

  4. Android App代码混淆终极解决方案

    App虽然没有那么的高大上,但是代码的混淆是代表了程序员对App的责任心, 也是对App安全的一点点保证.今天我会将自己做Android混淆的过程和体会分享给大家,也避免大家少走弯路,少跳坑. 本篇博 ...

  5. android app微信登录(android端+Java后台)

    本文demo下载:http://www.wisdomdd.cn/Wisdom/resource/articleDetail.htm?resourceId=885 本文章讲解如何在微信平台上传andro ...

  6. android沉浸式状态栏 图片背景,Android App 沉浸式状态栏解决方案

    伴随着 Android 5.0 发布的 Material Design,让 Android 应用告别了以前的工程师审美,迎来了全新的界面,灵动的交互,也让越来越多的 App 开始遵从 material ...

  7. shiro实现APP、web统一登录认证和权限管理

    先说下背景,项目包含一个管理系统(web)和门户网站(web),还有一个手机APP(包括Android和IOS),三个系统共用一个后端,在后端使用shiro进行登录认证和权限控制.好的,那么问题来了w ...

  8. Ajax跨域请求action方法,无法传递及接收cookie信息(应用于系统登录认证及退出)解决方案

    Ajax跨域请求action方法,无法传递及接收cookie信息(应用于系统登录认证及退出)解决方案 参考文章: (1)Ajax跨域请求action方法,无法传递及接收cookie信息(应用于系统登录 ...

  9. android 第三方登录界面,Android App集成第三方登录与换肤指南

    Android App集成第三方登录与换肤指南 文档编辑 概述 本文主要是介绍了如何通过开源框架快速支持QQ和微信登录,并介绍了如何实现app快速换肤 QQ登录接入 APP要支持QQ登录,需要先到腾讯 ...

  10. android系统性能优化(63)---Android APP 卡顿问题分析及解决方案

    Android APP 卡顿问题分析及解决方案 用户对卡顿的感知, 主要来源于界面的刷新. 而界面的性能主要是依赖于设备的UI渲染性能. 如果我们的UI设计过于复杂, 或是实现不够友好,计算绘制算法不 ...

最新文章

  1. 百度富文本编辑jsp上传_百度富文本编辑器教程,从入门到放弃
  2. Qt中的QPrintDialog
  3. php5.6.30源码下载,PHP 5.6.30 正式发布,安全漏洞修复
  4. JavaSE各阶段练习题----集合-Collection-Set-List
  5. 用纯css改变下拉列表select框的默认样式
  6. CString的成员函数用法大全
  7. Access 至少一个参数没有被指定值 解决方法
  8. Java中List,ArrayList、Vector,map,HashTable,HashMap区别用法
  9. ILSpy反编译exe文件,ResourceNet4修改properties,生成新的exe文件
  10. [洛谷] P3174 [HAOI2009]毛毛虫 (树形dp 树的最长直径的扩展)
  11. 雷电模拟器命令操作合集
  12. [转载]PS各个工具的字母快捷键和英文全名
  13. excel 无法求和
  14. php统计页面访问量_PHP 统计 网页 总访问次数 附代码
  15. 从零开始用uniapp搭建一个APP
  16. WHM系列:WHM数据迁移(WHM→WHM)
  17. 【第3篇】人工智能(AI)语音测试原理和实践
  18. word标题段前断后设置都为6磅,标题段前无效
  19. Nginx基本使用和代理服务器(负载均衡)--保姆级教程
  20. java设计模式之享元设计模式

热门文章

  1. windows资源保护无法启动修复服务器,Windows资源保护无法启动修复服务 | MOS86
  2. 单片机蓝桥杯之LED点亮(国信CT107D开发板)
  3. BLE DTM by HCI
  4. python系列3—顺序结构和分支结构
  5. postfix(邮件服务器)说明与postconfig命令详解
  6. cbox央视影音(CNTV客户端)广告屏蔽方法
  7. 【线代】相似矩阵中特征根的求法:特征方程、一般方程为什么求得的特征根含义不同?
  8. C51单片机控制蜂鸣器
  9. Qt自定义对话框及调用方法
  10. 201903-1小中大