您当前的位置:首页 > 电脑百科 > 程序开发 > 移动端 > Android

利用 Android Keystore系统 加密存储和解密敏感信息

时间:2019-08-27 09:59:47  来源:  作者:

利用 Android Keystore 系统,您可以在容器中存储加密密钥,从而提高从设备中提取密钥的难度。在密钥进入 Keystore 后,可以将它们用于加密操作,而密钥材料仍不可导出。此外,它提供了密钥使用的时间和方式限制措施,例如要求进行用户身份验证才能使用密钥,或者限制为只能在某些加密模式中使用。Keystore 系统由KeyChain API 以及在 Android 4.3(API 级别 18)中引入的 Android Keystore 提供程序功能使用。

以上便是google官方对于Android Keystore系统 的一些简单的介绍,简单的说Keystore 系统就是可以帮助我们完成一些我们应用中的一些比较私密敏感的信息的加密存储,以及解密,防止App的一些关键信息泄露。我们在实际开发中应该如何使用呢?这里我简单做个介绍,主要分为三步:第一步,密钥的创建。第二步,对我们的数据进行加密,然后最后当然就是我们要使用到数据的时候再对加密后的数据进行解密了。

密钥的创建

在密钥的创建之前我们先确定我们这里要使用到的加密算法,关于加密算法这一块有兴趣的同学可以自行Google,这里的例子使用到的加密算法为“AES / GCM / NoPadding”。此外我们还需要确定一个别名,这个别名是密钥在加解密过程中的一个识别连接,相当于我们在传递数据中的键值对中的键这样的一个作用。密钥获取的代码也不复杂,具体如下:

private SecretKey getSecretKey(final String alias) throws NoSuchAlgorithmException,
 NoSuchProviderException, InvalidAlgorithmParameterException 
 final KeyGenerator keyGenerator = KeyGenerator
 .getInstance(KeyProperties.KEY_ALGORITHM_AES, "AndroidKeyStore");
 keyGenerator.init(new KeyGenParameterSpec.Builder(alias,
 KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT)
 .setBlockModes(KeyProperties.BLOCK_MODE_GCM)
 .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE)
 .build());
 return keyGenerator.generateKey();

可以看到,我们首先创建得到一个密钥生成器KeyGenerator 的实例,其中两个参数的相关说明参看下图:

干货丨利用 Android Keystore系统 加密存储和解密敏感信息

 

然后使用 KeyGenerator 的实例初始化一些相关的配置,如上我们配置了密钥的别名,以及使用到的相关属性加密解密,setBlockModes 使我们确信仅指定可用于加密和解密的数据块模式中,如果使用的任何其他类型的块模式,它将被拒绝。由于我们使用 “AES / GCM / NoPadding” 转换算法,我们还告诉KeyGenParameterSpec应该使用的填充类型为NoPadding。至此,我们便完成了通过密钥生成器生成密钥的全部过程了。

数据加密

干货丨利用 Android Keystore系统 加密存储和解密敏感信息

 

我们加密的实际过程是通过Cipher 类来完成的,还是先看代码:

byte[] encryptText(final String alias, final String textToEncrypt)
 throws NoSuchAlgorithmException,
 NoSuchProviderException, NoSuchPaddingException, InvalidKeyException, IOException,
 InvalidAlgorithmParameterException, BadPaddingException, IllegalBlockSizeException 
 final Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
 cipher.init(Cipher.ENCRYPT_MODE, getSecretKey(alias));
 iv = cipher.getIV();
 return (encryption = cipher.doFinal(textToEncrypt.getBytes("UTF-8")));
}

可以看到我们首先得到了 Cipher 的实例,并指定了加密的算法为 "AES/GCM/NoPadding" ,然后直接初始化 Cipher 的实例指定为加密模式,并传入我们的第一步创建的密钥,这里我们存储 Cipher 初始化向量(IV),因为我们在解密的时候会用到。最后一步我们便直接调用 Cipher 的 doFinal 完成对数据的加密,doFinal方法返回一个字节数组,它是实际的加密文本,我们直接 Base64 编码一次就好:

Base64.encodeToString(encryptedText, Base64.DEFAULT)

数据解密

还是老规矩,先上代码:

 final Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
 final GCMParameterSpec spec = new GCMParameterSpec(128, encryptionIv);
 cipher.init(Cipher.DECRYPT_MODE, getSecretKey(alias), spec);
 return new String(cipher.doFinal(encryptedData), "UTF-8");}

其实加密与解密是一组对称的操作,解密其实就是加密的一个反向操作。同样的我们还是需要先获得 Cipher 的实例,然后我们通过GCMParameterSpec 类来赋予 Cipher 初始化向量的参数,这里简单的对 GCMParameterSpec 的两个参数进行说明,简单的块密码模式(例如CBC)通常只需要初始化向量(例如IvParameterSpec),但GCM需要以下参数:

  • IV:初始化向量(IV)
  • tLen:认证标签T的长度(以位为单位)

关于 GCMParameterSpec 的更多的信息可以自行查看文档,这里就不展开讨论了。

接下来跟加密一样的步骤,初始化 Cipher ,这里需要注意的一点便是我们密钥的获取:

private SecretKey getSecretKey(final String alias) throws NoSuchAlgorithmException,
 UnrecoverableEntryException, KeyStoreException {
 return ((KeyStore.SecretKeyEntry) keyStore.getEntry(alias, null)
}

我们通过我们最初设定的别名识别对应的密钥,从而通过 keyStore.getEntry(alias, null)).getSecretKey();方法进行获取得到。

至此我们便完成了通过Android Keystore 系统对APP中的关键信息进行加密以及解密的所有过程。

最后

如果你看到了这里,觉得文章写得不错就给个赞呗!如果你觉得那里值得改进的,请给我留言。一定会认真查询,修正不足,谢谢。定期免费分享技术干货。欢迎大家点赞关注。



Tags:Keystore系统   点击:()  评论:()
声明:本站部分内容及图片来自互联网,转载是出于传递更多信息之目的,内容观点仅代表作者本人,如有任何标注错误或版权侵犯请与我们联系(Email:2595517585@qq.com),我们将及时更正、删除,谢谢。
▌相关推荐
利用 Android Keystore 系统,您可以在容器中存储加密密钥,从而提高从设备中提取密钥的难度。在密钥进入 Keystore 后,可以将它们用于加密操作,而密钥材料仍不可导出。此外,它提供...【详细内容】
2019-08-27  Tags: Keystore系统  点击:(399)  评论:(0)  加入收藏
▌简易百科推荐
今天面试遇到同学说做过内存优化,于是我一般都会问那 Bitmap 的像素内存存在哪?大多数同学都回答在 java heap 里面,就比较尴尬,理论上你做内存优化,如果连图片这个内存大户内存...【详细内容】
2021-12-23  像程序那样思考    Tags:Android开发   点击:(8)  评论:(0)  加入收藏
Android logcat日志封装logcat痛点在Android开发中使用logcat非常频繁,logcat能帮我们定位问题,但是在日常使用中发现每次使用都需要传递tag,并且会遇到输出频率很高的log,在多...【详细内容】
2021-12-22  YuCoding    Tags:Android   点击:(8)  评论:(0)  加入收藏
对项目的基本介绍 1.整个框架主要是给MVVM框架使用的,自己写完interface接口后,通过自定义的注解就能自动生成接口方法 2.用Kotlin的Flow去代替Rxjava,因为我发现RxJava功能很...【详细内容】
2021-12-08  网易Leo    Tags:Android开发   点击:(17)  评论:(0)  加入收藏
前言在Android开发过程中,有些时候会根据需要引用别的项目到当前项目里面,而且以Module形式引用。所以本篇博文就来分享一下怎么以Module形式引用别的项目到当前项目中,方便开...【详细内容】
2021-12-07  网易Leo    Tags:Android开发   点击:(22)  评论:(0)  加入收藏
作者:fundroid这篇文章偏阅读一些,大家可以了解下 Android 的一些最新动向。每年9/10月份 Google 都会举行约为期2天的 Android Dev Summit,在活动上 Google 的技术专家们会分...【详细内容】
2021-11-30  像程序那样思考    Tags:Android开发   点击:(15)  评论:(0)  加入收藏
一、 准备工作1、安装JDK,下载地址(可能需要一个oracle账号,大家百度一下或者自行注册一个就行。尽可能选择8或者11,这两个是长期版本)Java SE | Oracle Technology Network | Or...【详细内容】
2021-11-23  永沧    Tags:Android   点击:(28)  评论:(0)  加入收藏
使用Maven Publish Plugin插件。(官方支持)一、在Library的build.gradle中配置plugins { id 'com.android.library' id 'kotlin-android' id 'k...【详细内容】
2021-11-05  羊城小阳    Tags:Android   点击:(37)  评论:(0)  加入收藏
谷歌离推出Play Store应用程序的新数据隐私部分又近了一步。应用程序开发人员现在可以通过谷歌在Play控制台的新 "数据安全表 "填写相关细节。该公司表示,所需信息将从2022年...【详细内容】
2021-10-20    中关村在线  Tags:安卓   点击:(58)  评论:(0)  加入收藏
架构究竟是什么?如何更好的理解架构?我们知道一个APP通常是由class组成,而这些class之间如何组合,相互之间又如何产生作用,就是影响这个APP的关键点。细分的话我们可以将其分为类...【详细内容】
2021-09-17  像程序那样思考    Tags:Android架构   点击:(52)  评论:(0)  加入收藏
概述当Android应用程序需要访问设备上的敏感资源时,应用程序开发人员会使用权限模型。虽然该模型使用起来非常简单,但开发人员在使用权限时容易出错,从而导致安全漏洞。本文中,...【详细内容】
2021-09-07  SecTr安全团队    Tags:Android开发   点击:(66)  评论:(0)  加入收藏
相关文章
    无相关信息
最新更新
栏目热门
栏目头条