我的编程空间,编程开发者的网络收藏夹
学习永远不晚

Android 免密支付+Keystore体系

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

Android 免密支付+Keystore体系

首先我们要实现这个功能需要确认几个问题

1.如何创建一个Keystore并保证其唯一性
2.如何设置KeyProtection
3.如何把密钥也就是密码放到安卓Keystore里面
4.如何通过指纹获取到Keystore里面存储的密码
5.当指纹变更之后如何失效
6. secret key的作用,对称加密
7.指纹验证通过之后如何获取到存储在Android Keystore里面密文
这个问题可以分成两个问题看待,第一个问题是安卓的Keystore体系,第二个是生物识别

参考文章:
Android指纹识别,看这一篇就够了
Android 保存私密信息-强大的 keyStore
Android KeyStore + FingerprintManager 存储密码

Keystore体系 创建一个密钥(SecretKey)

安卓内部是提供一套Keystore体系用于用户加密的,我们可以通过

 KeyStore androidKeyStore = KeyStore.getInstance(ANDROID_KEY_STORE);//获取到Android的Keystore类

我们所获取的androidKeyStore 就是安卓系统的keystore

“AndroidKeyStore”:这里要先区分下AndroidKeyStore和Android
KeyStore,虽然这两个一样,但是后者中间多了个空格,意义是不一样的,前者是子集,后者是父集,后者包含前者。而AndroidKeyStore主要是用来存储一些密钥key的,存进该处的key可以为其设置KeyProtection,例如只能通过用户验证才能取出key使用等。这些key是存在系统里的,不是在app的目录下,并且每个app不能访问其他app的key,如果app1创建了key1,并且存储的时候命名为temp,app2去通过temp去访问key,是获取不到的!!
KeyStore.getDefaultType():该函数返回的是一个字符串,在java下,返回的是JKS,在Android下,返回的是BKS(
生成android使用的BKS证书)。(注:android
系统中使用的证书要求以BKS的库文件结构保存,通常情况下,我们使用java的keytool只能生成jks的证书库。读取key可以通过psw来读取)。当你使用这个keystore的时候,其文件存放在data(沙盒中)

之后我们需要对这个Keystore做一下初始化参数,我们才能生成一个真正属于自己的可以加密的系统

 KeyStore androidKeyStore = KeyStore.getInstance(ANDROID_KEY_STORE);
            androidKeyStore.load(null);
            KeyGenerator keyGenerator = KeyGenerator.getInstance(KeyProperties.KEY_ALGORITHM_AES, "AndroidKeyStore");
            KeyGenParameterSpec spec = new KeyGenParameterSpec.Builder(DEFAULT_KEY_NAME,
                    KeyProperties.PURPOSE_ENCRYPT |
                            KeyProperties.PURPOSE_DECRYPT)
                                               .setBlockModes(KeyProperties.BLOCK_MODE_CBC)
                                               .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_PKCS7)
                                               //这个设置为true,表示这个key必须是通过了用户认证才可以使用
                                               .setUserAuthenticationRequired(true)
                                               .build();
            keyGenerator.init(spec);
            SecretKey secretKey = keyGenerator.generateKey();

其中 androidKeyStore.load(null);这一点尤其关键
load

Added in API level 1 public final void load (InputStream stream,
char[] password) Loads this KeyStore from the given input stream. A password may be given to unlock the keystore (e.g. the
keystore resides on a hardware token device), or to check the
integrity of the keystore data. If a password is not given for
integrity checking, then integrity checking is not performed. In order
to create an empty keystore, or if the keystore cannot be initialized
from a stream, pass null as the stream argument. Note that if this
keystore has already been loaded, it is reinitialized and loaded again
from the given input stream.

Google官方文档给出的解释,load(null)是重新创建一个新的Keysotre密钥库

加密

接下来我们获取到了密钥,然后我们就可以初始化Cipher 对象,这将是实际的加密过程

 Cipher cipher = null;
        cipher = Cipher.getInstance(KeyProperties.KEY_ALGORITHM_AES + "/"
                                            + KeyProperties.BLOCK_MODE_CBC + "/"
                                            + KeyProperties.ENCRYPTION_PADDING_PKCS7);
        cipher.init(Cipher.ENCRYPT_MODE, secretKey);
        return cipher;

我们获取到的Cipher就是密文
同时这里我们需要获取到IV初始化向量,这个东西很重要,对于未来我们做解密的时候获取密码的唯一性很重要
引入了一个新的概念:初始向量IV(Initialization Vector)。

IV是做什么用的呢?它的作用和MD5的“加盐”有些类似,目的是防止同样的明文块始终加密成同样的密文块。

  byte[] iv = cipher.getIV();

这个iv需要保存好,是为了之后解密的时候我们定义其唯一性

解密
 Cipher cipher = null;
        cipher = Cipher.getInstance(KeyProperties.KEY_ALGORITHM_AES + "/"
                                            + KeyProperties.BLOCK_MODE_CBC + "/"
                                            + KeyProperties.ENCRYPTION_PADDING_PKCS7);
        IvParameterSpec ivParameterSpec = new IvParameterSpec(initializeVector);
        cipher.init(Cipher.DECRYPT_MODE,secretKey , ivParameterSpec);
生物识别体系

生物识别,这里我主要是实现了指纹识别,
在安卓体系下,提供了API23和API28的系统生物识别类,23的FingerprintManager 以及28的BiometricPrompt
至于两者的区别网上有很多研究,这里先不管 主要说核心方法

API23
new FingerprintManager.CryptoObject(Cipher cipher);
API28
new BiometricPrompt.CryptoObject(Cipher cipher); //这里就用到了上文中通过Keystore生成的密文了

我的理解是通过这一步就是实现了 Keystore和生物识别的绑定

之后我们会获取到 CryptoObject
然后调用 各自的 authenticate()方法就可以获取系统指纹的回调了

然后我们就可以实现生物识别功能了,关于里面的参数以及错误码的监听,网上的攻略比较多,我开头留的文章就可以找到

总结:这篇文章主要讲了如何通过生物识别把密码保存到Keysotre里面,然后生物识别通过之后取出密码的过程,有些地方写的不是很全,但是总体来说是没问题的。


作者:没事遛自己


免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

Android 免密支付+Keystore体系

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

Android 免密支付+Keystore体系

首先我们要实现这个功能需要确认几个问题 1.如何创建一个Keystore并保证其唯一性 2.如何设置KeyProtection 3.如何把密钥也就是密码放到安卓Keystore里面 4.如何通过指纹获取到Keystore里面存储的密码 5.
2022-06-06

编程热搜

  • Android:VolumeShaper
    VolumeShaper(支持版本改一下,minsdkversion:26,android8.0(api26)进一步学习对声音的编辑,可以让音频的声音有变化的播放 VolumeShaper.Configuration的三个参数 durati
    Android:VolumeShaper
  • Android崩溃异常捕获方法
    开发中最让人头疼的是应用突然爆炸,然后跳回到桌面。而且我们常常不知道这种状况会何时出现,在应用调试阶段还好,还可以通过调试工具的日志查看错误出现在哪里。但平时使用的时候给你闹崩溃,那你就欲哭无泪了。 那么今天主要讲一下如何去捕捉系统出现的U
    Android崩溃异常捕获方法
  • android开发教程之获取power_profile.xml文件的方法(android运行时能耗值)
    系统的设置–>电池–>使用情况中,统计的能耗的使用情况也是以power_profile.xml的value作为基础参数的1、我的手机中power_profile.xml的内容: HTC t328w代码如下:
    android开发教程之获取power_profile.xml文件的方法(android运行时能耗值)
  • Android SQLite数据库基本操作方法
    程序的最主要的功能在于对数据进行操作,通过对数据进行操作来实现某个功能。而数据库就是很重要的一个方面的,Android中内置了小巧轻便,功能却很强的一个数据库–SQLite数据库。那么就来看一下在Android程序中怎么去操作SQLite数
    Android SQLite数据库基本操作方法
  • ubuntu21.04怎么创建桌面快捷图标?ubuntu软件放到桌面的技巧
    工作的时候为了方便直接打开编辑文件,一些常用的软件或者文件我们会放在桌面,但是在ubuntu20.04下直接直接拖拽文件到桌面根本没有效果,在进入桌面后发现软件列表中的软件只能收藏到面板,无法复制到桌面使用,不知道为什么会这样,似乎并不是很
    ubuntu21.04怎么创建桌面快捷图标?ubuntu软件放到桌面的技巧
  • android获取当前手机号示例程序
    代码如下: public String getLocalNumber() { TelephonyManager tManager =
    android获取当前手机号示例程序
  • Android音视频开发(三)TextureView
    简介 TextureView与SurfaceView类似,可用于显示视频或OpenGL场景。 与SurfaceView的区别 SurfaceView不能使用变换和缩放等操作,不能叠加(Overlay)两个SurfaceView。 Textu
    Android音视频开发(三)TextureView
  • android获取屏幕高度和宽度的实现方法
    本文实例讲述了android获取屏幕高度和宽度的实现方法。分享给大家供大家参考。具体分析如下: 我们需要获取Android手机或Pad的屏幕的物理尺寸,以便于界面的设计或是其他功能的实现。下面就介绍讲一讲如何获取屏幕的物理尺寸 下面的代码即
    android获取屏幕高度和宽度的实现方法
  • Android自定义popupwindow实例代码
    先来看看效果图:一、布局
  • Android第一次实验
    一、实验原理 1.1实验目标 编程实现用户名与密码的存储与调用。 1.2实验要求 设计用户登录界面、登录成功界面、用户注册界面,用户注册时,将其用户名、密码保存到SharedPreference中,登录时输入用户名、密码,读取SharedP
    Android第一次实验

目录