热门标签 | HotTags
当前位置:  开发笔记 > Android > 正文

Android使用KeyStore对数据进行加密的示例代码

这篇文章主要介绍了Android使用KeyStore对数据进行加密的示例代码,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

谈到 Android 安全性话题,Android Developers 官方网站给出了许多很好的建议和讲解,涵盖了存储数据、权限、网络、处理凭据、输入验证、处理用户数据、加密等方方面面

密钥的保护以及网络传输安全 应该是移动应用安全最关键的内容。Android 提供大量用来保护数据的加密算法,例如 Cipher 类中提供了 AES 和 RSA 算法,再例如安全随机数生成器 SecureRandom 给 KeyGenerator 提供了更加可靠的初始化参数,避免离线攻击等等。

而如果需要存储密钥以供重复使用,Android 提供了 KeyStore 等可以长期存储和检索加密密钥的机制,Android KeyStore 系统特别适合于存储加密密钥。”AndroidKeyStore” 是 KeyStore 的一个子集,存进 AndroidKeyStore 的 key 将受到签名保护,并且这些 key 是存在系统里的,而不是在 App 的 data 目录下,依托于硬件的 KeyChain 存储,可以做到 private key 一旦存入就无法取出,总之,每个 App 自己创建的 key,别的应用是访问不到的。

KeyStore 提供了两个能力:

有了这两个能力,我们的密钥保护就变得很容易了,你只需要:

在应用安装后第一次运行时,生成一个随机密钥,并存入 KeyStore

当你想存储一个数据,便从 KeyStore 中取出之前生成的随机密钥,对你的数据进行加密,加密完成后,已完成加密的数据可以随意存储在任意地方,比如 SharePreferences,此时即使它被他人读取到,也无法解密出你的原数据,因为他人取不到你的密钥

当你需要拿到你的原数据,只需要从 SharePreferences 中读取你加密后的数据,并从 KeyStore 取出加密密钥,使用加密密钥对 “加密后的数据” 进行解密即可

其中加密算法可以使用 Cipher AES 来保证安全性,不要使用自己创造的加密算法。

这就是使用 KeyStore 的一整套流程,另外 KeyStore 还可以用来做数据签名和签名验证,就像一个黑匣子一样,具体可以自行搜索了解。

KeyStore 适于存储运行时生产获取到的数据,比如运行时,用户输入的密码,或者服务端传下来的 token,但无法用于存储我们需要预设在 App 内的 API key / secret,对于这类需要预设的固定密钥,我将介绍一种十分安全、难破解的保护方式。

加密:

public String encryptString(String needEncryptWord, String alias) {
    if(!"".equals(alias)&&!"".equals(needEncryptWord)){
      if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
        initKeyStore(alias);
      }
      String encryptStr="";
      byte [] vals=null;
      try {
        KeyStore.PrivateKeyEntry privateKeyEntry = (KeyStore.PrivateKeyEntry)keyStore.getEntry(alias, null);
//      RSAPublicKey publicKey = (RSAPublicKey) privateKeyEntry.getCertificate().getPublicKey();
        if(needEncryptWord.isEmpty()) {
//        Toast.makeText(this, "Enter text in the 'Initial Text' widget", Toast.LENGTH_LONG).show();
          return encryptStr;
        }

//      Cipher inCipher = Cipher.getInstance("RSA/ECB/PKCS1Padding", "AndroidOpenSSL");
        Cipher inCipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
//      inCipher.init(Cipher.ENCRYPT_MODE, publicKey);
        inCipher.init(Cipher.ENCRYPT_MODE, privateKeyEntry.getCertificate().getPublicKey());

        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        CipherOutputStream cipherOutputStream = new CipherOutputStream(
            outputStream, inCipher);
        cipherOutputStream.write(needEncryptWord.getBytes("UTF-8"));
        cipherOutputStream.close();

        vals = outputStream.toByteArray();
      } catch (Exception e) {
        e.printStackTrace();
      }
      return Base64.encodeToString(vals, Base64.DEFAULT);
    }
    return "";
  }

解密:

public String decryptString(String needDecryptWord, String alias) {
    if(!"".equals(alias)&&!"".equals(needDecryptWord)){
      if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
        initKeyStore(alias);
      }
      String decryptStr="";
      try {
        KeyStore.PrivateKeyEntry privateKeyEntry = (KeyStore.PrivateKeyEntry)keyStore.getEntry(alias, null);
//      RSAPrivateKey privateKey = (RSAPrivateKey) privateKeyEntry.getPrivateKey();

//      Cipher output = Cipher.getInstance("RSA/ECB/PKCS1Padding", "AndroidOpenSSL");
        Cipher output = Cipher.getInstance("RSA/ECB/PKCS1Padding");
//      output.init(Cipher.DECRYPT_MODE, privateKey);
        output.init(Cipher.DECRYPT_MODE, privateKeyEntry.getPrivateKey());
        CipherInputStream cipherInputStream = new CipherInputStream(
            new ByteArrayInputStream(Base64.decode(needDecryptWord, Base64.DEFAULT)), output);
        ArrayList values = new ArrayList<>();
        int nextByte;
        while ((nextByte = cipherInputStream.read()) != -1) {
          values.add((byte)nextByte);
        }

        byte[] bytes = new byte[values.size()];
        for(int i = 0; i 

源码下载地址,我已经将加密解密封装进了工具类,并对Android 7.0的兼容也处理了

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。


推荐阅读
  • Java面向对象编程深入解析
    本文详细探讨了Java中的关键字static、单例模式、main()方法、代码块、final关键字、抽象类与方法、模板方法设计模式、接口、内部类等内容,旨在帮助读者深入理解和掌握Java面向对象编程的核心概念。 ... [详细]
  • 本文深入探讨了Redis中的两种主要持久化方式——RDB(Redis Database)和AOF(Append Only File),并详细解析了两者的实现机制、优缺点以及在实际应用中的选择策略。 ... [详细]
  • 2017成都物流技术创新峰会:深入探讨区块链应用
    2017年3月30日,第二届物流技术大会在成都成功举办,会上特别举办了关于区块链技术及其在物流行业应用的专题讨论,深入分析了区块链技术的发展历程、现状及未来趋势。 ... [详细]
  • GNU GRUB(简称GRUB)是一个来自GNU项目的支持多启动的引导加载程序。它允许用户在同一台计算机上安装多个操作系统,并在启动时选择希望启动的系统。 ... [详细]
  • 随着技术的发展,黑客开始利用AI技术在暗网中创建用户的‘数字孪生’,这一现象引起了安全专家的高度关注。 ... [详细]
  • 介绍一个基于区块链技术的分布式存储项目,其提供的网盘服务速度远超传统网盘,如百度网盘,最高可达5倍之多。 ... [详细]
  • NFC OMA 接口访问优化
    本文探讨了NFC设备中OMA接口的访问方式,特别是针对IC制造商提供的NFC swp-sim访问与NFC服务提供商对eSe(嵌入式安全元件)访问的不同处理方法。文中提出了几种解决方案以解决由此产生的双SmartcardService运行问题。 ... [详细]
  • 一面问题:MySQLRedisKafka线程算法mysql知道哪些存储引擎,它们的区别mysql索引在什么情况下会失效mysql在项目中的优化场景&# ... [详细]
  • 开发笔记:哈希的应用
    开发笔记:哈希的应用 ... [详细]
  • 解析EasyCVR平台国标GB28181协议下的TCP与UDP模式
    在使用EasyCVR视频融合平台过程中,用户常遇到关于端口设置的问题,尤其是TCP和UDP模式的区别。本文将详细介绍这两种模式在GB28181协议下的具体应用及差异。 ... [详细]
  • NIO 通道接口详解
    本文介绍了NIO(New Input/Output)中的通道接口及其相关概念,包括通道的基本功能、接口设计以及各类通道接口的具体用途。通过本文,读者可以深入了解NIO通道的设计原理及其在实际项目中的应用。 ... [详细]
  • 近年来,随着HTTPS加密技术的普及,许多网站开始采用这一技术来保障数据安全。然而,近日发现的一种新型木马利用中间人攻击手段,成功绕过HTTPS的安全防护,每日影响超过200万次的网络访问。 ... [详细]
  • Linux环境下Redmine快速搭建指南
    本文将详细介绍如何在Linux操作系统中使用Bitnami Redmine安装包快速搭建Redmine项目管理平台,帮助读者轻松完成环境配置。 ... [详细]
  • 本文深入探讨了服务器的主要作用,包括加速访问、增强安全性和绕过访问限制等,并详细介绍了如何正确配置代理服务器。 ... [详细]
  • 本文探讨了即使实现了财务自由,为何仍有许多人选择继续职场拼搏的原因,以及这种选择背后的深层心理与职业动力。阅读大约需要4分钟。 ... [详细]
author-avatar
倾其h所有只为爱你
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有