Android开发 之 确认凭证

2023-05-16

确认凭证

主要目的:设置不用验证时间 设置为30秒,当超过30秒后则需要重新验证身份才能操作。
您的应用可以根据用户在多久之前最后一次解锁设备来验证其身份。此功能让用户不必费心记忆应用特定密码,您也无需实现自己的身份验证用户界面。您的应用应当利用此功能并结合实现公钥或私钥,以进行用户身份验证。

要设置成功验证用户身份后可再次使用同一密钥的超时持续时间,请在设置 KeyGenerator 或 KeyPairGenerator 时调用新增的 setUserAuthenticationValidityDurationSeconds() 方法。
避免过多显示重新验证对话框 -- 您的应用应尝试先使用加密对象,如果超时到期,请使用 createConfirmDeviceCredentialIntent() 方法在您的应用内重新验证用户身份。
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <Button
        android:id="@+id/button"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:onClick="button"
        android:text="输入密码确认凭据"/>
    <TextView
        android:id="@+id/already_has_valid_device_credential_message"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textSize="20sp"
        />

</LinearLayout>

package th.zxq.com.android60;

import android.app.KeyguardManager;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.security.keystore.KeyGenParameterSpec;
import android.security.keystore.KeyPermanentlyInvalidatedException;
import android.security.keystore.KeyProperties;
import android.security.keystore.UserNotAuthenticatedException;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

import java.io.IOException;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.UnrecoverableKeyException;
import java.security.cert.CertificateException;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.KeyGenerator;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;

/**
 * Created by Administrator on 2017/8/14.
 */

public class SurePJActivity extends AppCompatActivity {
    private static final String KEY_NAME = "my_key";//我们的钥匙在Android钥匙商店的别名。
    private static final int AUTHENTICATION_DURATION_SECONDS = 30;//设置多少秒后重新验证身份
    private static final byte[] SECRET_BYTE_ARRAY = new byte[] {1, 2, 3, 4, 5, 6};
    private KeyguardManager mKeyguardManager;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_surepj);
        Button button= (Button) findViewById(R.id.button);
        mKeyguardManager = (KeyguardManager) getSystemService(Context.KEYGUARD_SERVICE);
        //检测是否设置安全密码或者指纹,有无安全保护。
        if (!mKeyguardManager.isKeyguardSecure()) {
            Toast.makeText(this, "去设置->安全录入密码或者指纹", Toast.LENGTH_LONG).show();
            button.setEnabled(false);
            return;
        }
        createKey();
    }
    public void button(View view)
    {
        tryEncrypt();
    }
    /**
     * Tries to encrypt some data with the generated key in {@link #createKey} which is
     * only works if the user has just authenticated via device credentials.
     * 尝试使用{@link #createKey}中生成的密钥加密某些数据,只有在用户刚刚通过设备凭据进行身份验证时,该数据才有效。
     */
    private boolean tryEncrypt() {
        try {
            KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore");
            keyStore.load(null);
            SecretKey secretKey = (SecretKey) keyStore.getKey(KEY_NAME, null);
            Cipher cipher = Cipher.getInstance(
                    KeyProperties.KEY_ALGORITHM_AES + "/" + KeyProperties.BLOCK_MODE_CBC + "/"
                            + KeyProperties.ENCRYPTION_PADDING_PKCS7);

            // Try encrypting something, it will only work if the user authenticated within
            // the last AUTHENTICATION_DURATION_SECONDS seconds.
            // 尝试加密某些东西,只有用户在最后一次认证30秒内进行身份验证,才能工作。超过30秒后在操作就会报异常
            cipher.init(Cipher.ENCRYPT_MODE, secretKey);
            cipher.doFinal(SECRET_BYTE_ARRAY);

            // If the user has recently authenticated, you will reach here.
            //如果用户最近已通过身份验证,您将到达这里。
            showAlreadyAuthenticated();
            return true;
        } catch (UserNotAuthenticatedException e) {
            // User is not authenticated, let's authenticate with device credentials.
            showAuthenticationScreen();
            return false;
        } catch (KeyPermanentlyInvalidatedException e) {
            // This happens if the lock screen has been disabled or reset after the key was
            // generated after the key was generated.
            //如果在生成密钥后锁定屏幕已被禁用或复位,则会发生这种情况。
            Toast.makeText(this, "Keys are invalidated after created. Retry the purchase\n"
                            + e.getMessage(),
                    Toast.LENGTH_LONG).show();
            return false;
        } catch (BadPaddingException | IllegalBlockSizeException | KeyStoreException |
                CertificateException | UnrecoverableKeyException | IOException
                | NoSuchPaddingException | NoSuchAlgorithmException | InvalidKeyException e) {
            throw new RuntimeException(e);
        }
    }
    /**
     * 在Android Key Store中创建一个对称密钥,只能在用户在最近X秒内通过身份验证身份验证后使用。
     */
    public void createKey()
    {
        // 生成一个密钥来解密支付凭证,令牌等。
        try {
            KeyStore androidKeyStore = KeyStore.getInstance("AndroidKeyStore");
            androidKeyStore.load(null);
            KeyGenerator keyGenerator = KeyGenerator.getInstance(
                    KeyProperties.KEY_ALGORITHM_AES, "AndroidKeyStore");

            // Set the alias of the entry in Android KeyStore where the key will appear
            // and the constrains (purposes) in the constructor of the Builder
            //设置Android KeyStore中出现密钥的条目的别名,以及Builder的构造函数中的约束(目的)
            keyGenerator.init(new KeyGenParameterSpec.Builder(KEY_NAME,
                    KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT)
                    .setBlockModes(KeyProperties.BLOCK_MODE_CBC)
                    .setUserAuthenticationRequired(true)
                    // Require that the user has unlocked in the last 30 seconds
                    //要求用户在过去30秒内解锁,6.0新api
                    .setUserAuthenticationValidityDurationSeconds(AUTHENTICATION_DURATION_SECONDS)
                    .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_PKCS7)
                    .build());
            keyGenerator.generateKey();
        } catch (NoSuchAlgorithmException | NoSuchProviderException
                | InvalidAlgorithmParameterException | KeyStoreException
                | CertificateException | IOException e) {
            throw new RuntimeException("Failed to create a symmetric key", e);
        }
    }
    private void showAuthenticationScreen() {
        //创建“确认凭据”屏幕。 您可以自定义标题和说明。
        // Create the Confirm Credentials screen. You can customize the title and description. Or
        //如果您将其留空,我们将为您提供一个通用的
        // we will provide a generic one for you if you leave it null
        Intent intent = mKeyguardManager.createConfirmDeviceCredentialIntent(null, null);
        if (intent != null) {
            startActivityForResult(intent, 1);
        }
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (requestCode == 1) {
            // Challenge completed, proceed with using cipher
            if (resultCode == RESULT_OK) {
                if (tryEncrypt()) {
                    MyUitls.showToast(SurePJActivity.this,"验证通过了");
                }
            } else {
                // The user canceled or didn’t complete the lock screen
                // operation. Go to error/cancellation flow.
            }
        }
    }
    private void showAlreadyAuthenticated() {
        TextView textView = (TextView) findViewById(
                R.id.already_has_valid_device_credential_message);
        textView.setVisibility(View.VISIBLE);
        textView.setText(getString(R.string.already_confirmed_device_credentials_within_last_x_seconds, AUTHENTICATION_DURATION_SECONDS));
        findViewById(R.id.button).setEnabled(false);
    }
}

<resources>
    <string name="app_name">Android6.0</string>
    <string name="already_confirmed_device_credentials_within_last_x_seconds">验证通过后,%1$s 秒之内不用验证,锁屏秒数重置</string>
</resources>


本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Android开发 之 确认凭证 的相关文章

  • mvp契约类

    public class MainActivity extends AppCompatActivity implements IContract IView private IContract IPresenter presenter 64
  • Rxjava和Retrofit结合使用大量请求时候出现OOM的问题

    在使用RxJava 43 Retrofit的过程中 出现了OOM的问题 报错日志如下 java lang OutOfMemoryError pthread create 1040KB stack failed Try again at ja
  • vc++中进程间的通信

    进程通常被定义为一个正在运行的程序的实例 xff0c 它由两个部分组成 xff1a 一个是操作系统用来管理进程的内核对象 内核对象也是系统用来存放关于进程的统计信息的地方 另一个是地址空间 xff0c 它包含所有的可执行模块或DLL模块的代
  • 如何用YOLO+Tesseract实现定制OCR系统

    转载 AI开发者 xff1a https mp weixin qq com s Eq6POwgyME WJYK9NWpzDw 什么是 OCR xff1f OCR 指的是光学字符识别 它用于从扫描的文档或图片中读取文本 这项技术被用来将几乎任
  • cnn-过拟合(over-fitting)

    概念 为了得到一致假设而使假设变得过度严格称为过拟合 1 给定一个假设空间H xff0c 一个假设h属于H xff0c 如果存在其他的假设h 属于H 使得在训练样例上h的错误率比h 小 xff0c 但在整个实例分布上h 比h的错误率小 xf
  • cnn-欠拟合(underfitting)

    模型不能很好拟合数据 称之为欠拟合 直白的说 xff1a 模型没有找到数据规律或不完整 xff0c 泛化能力不强 在训练和测试数据集上 xff0c 预测或训练结果都和真实结果相差很远 一般解决方法 增加新特征 xff0c 可以考虑加入进特征
  • ERROR: Command errored out with exit status 1: python setup.py egg_info Check the logs for full comm

    类似这种问题 xff0c 不一定是pip版本不对 xff0c 有可能是某个文件不存在 xff0c 例如 在python3 5环境中安装scikit image pip install scikit image 61 61 0 12 就出现
  • AI最新资讯,持续更新

    三星 人造人 项目曝光 xff01 效果太逼真 xff0c 可自主生成新表情 动作和对话 https mp weixin qq com s 417fL3oYVE1vOwsVHMmqow Det3D 首个通用 3D 目标检测框架 https
  • 二维码生成以及扫一扫解析二维码原理

    二维码生成以及扫一扫解析二维码原理 1 生成URL xff0c 确定要通过二维码传达的信息 xff0c 也就是通过扫一扫可以获得地址和数据信息 1 得到随机数 xff0c 用随机数得到签名 xff0c 签名验证身份 String ranSt
  • idea 不能生成target

    1 改module https blog csdn net qq 15304369 article details 93715206 2 pom配置文件 修改为 xff1a lt packaging gt jar lt packaging
  • mariadb 遇到的坑

    mariadb13 3 25 配置文件失效 xff08 折腾了很久 xff09 xff0c 当时我需要配置主从 xff0c 发现binlog无法打开 xff0c 配置了bin log项还是不行 xff01 当my cnf 文件权限过大时 x
  • CV资料汇总

    1 图像风格迁移 Neural Style 简史 https www sohu com a 221597595 236505 2 一文让你理解什么是卷积神经网络 https www jianshu com p 1ea2949c0056
  • skinmagic 对话框菜单展示

    我偶用skinmagic xff0c 在换对话框皮肤时候 xff0c 发现菜单不见了 xff0c 几经折腾 xff0c 发现SetWindowSkin m hWnd 34 Dialog 34 在iniInstance xff08 xff09
  • 系统如何支持高并发

    给个例子 xff0c 你的系统部署的机器是4核8G xff0c 数据库服务器是16核32G 此时假设你的系统用户量总共就10万 xff0c 用户量很少 xff0c 日活用户按照不同系统的场景有区别 xff0c 我们取一个较为客观的比例 xf
  • Firewalld防火墙基础

    目录 一 Firewalld 概述 1 1 Firewalld的简述 1 2 Firewalld 和 iptables的区别 1 3 firewalld的区域 1 3 1 firewalld的9个区域 1 3 2 firewalld的数据处
  • CentOS7安装Oracle JDK

    CentOS7默认安装的是OpenJDK 如果安装Oracle JDK xff0c 需要按如下方式操作 xff1a 1 登录http www oracle com technetwork java javase downloads inde
  • 百度2014校招笔试题(一)

    算法和程序设计题 xff1a 1 题意 xff1a 一幢大楼的底层有1001根电线 xff0c 这些电线一直延伸到大楼楼顶 xff0c 你需要确定底层的1001个线头和楼顶的1001次线头的对应关系 你有一个电池 xff0c 一个灯泡 xf
  • Acwing 1175.最大联通子图(tarjan缩点求scc)

    Acwing 1175 最大连通子图 题意 一个有向图 G 61 V E G 61 V
  • 用github搭建个人(博客网站

    x1f308 博客主页 xff1a 卿云阁 x1f48c 欢迎关注 x1f389 点赞 x1f44d 收藏 留言 x1f4dd x1f31f 本文由卿云阁原创 xff01 x1f64f 作者水平很有限 xff0c 如果发现错误 xff0c
  • 多线程下HashMap的死循环

    多线程下HashMap的死循环 Java的HashMap是非线程安全的 多线程下应该用ConcurrentHashMap 多线程下 HashMap 的问题 xff08 这里主要说死循环问题 xff09 xff1a 1 多线程put操作后 x

随机推荐

  • 找出一个图中所有的强连通子图

    如果一个有向图中的没对顶点都可以从通过路径可达 xff0c 那么就称这个图是强连通的 一个 strongly connected component就是一个有向图中最大的强连通子图 下图中就有三个强连通子图 xff1a 应用kosaraju
  • win7启动分区不存在,使用分区工具修正

    DiskGenius 分区右键 激活当前分区
  • getElementById获取不到td标签

    一次测试中发现 然后使用getElementById获取不到此标签 xff0c 将td改成div即可 不知道是不是单独使用td标签的问题 code
  • 应用宝YSDK支付接入技术细节

    前言 应用宝是出了名的坑 xff0c 主要体现在 xff1a 文档杂乱繁多信息不全或描述模糊文档格式不规范技术支持很不及时 并且可以明显察觉到为了兼容QQ和微信 xff0c 应用宝的接入规范有诸多不合理的地方 来来回回折腾了一周 xff0c
  • 用Word2007批量设置图片位置

    转自 xff1a http www ccw com cn college htm2010 20100727 877695 shtml Word2007的 查找和替换 功能并不仅仅可以对文字进行批量的查找替换 xff0c 还有很多神奇的功能
  • java-生产者消费者问题以及解决办法

    文章目录 1 生产者消费者问题概述2 生产者消费者问题的解决办法2 1 解决思路2 2 实现方法2 3 代码实现2 3 1 wait 和nofity 方法2 3 2 await signal 方法2 3 3 BlockingQueue阻塞队
  • 【Remote Development】VSCode 基于 SSH 进行远程开发

    系统需求 我们在 VSCode 下载由微软官方推出的 Remote SSH 插件 查看一下里面的描述 xff0c 对于远程机器的要求如下 xff1a Local A supported OpenSSH compatible SSH clie
  • git idea创建新分支,获取/合并主支代码的2个方法

    其他sql格式也在更新中 xff0c 可直接查看这个系列 xff0c 要是没有你需要的格式 xff0c 可在评论或私信我 个人目录 获取主支代码的2个方法 1 xff0c 创建一个分支 xff0c 获取主支的所有代码 xff08 场景 xf
  • spring手把手超详细讲解(基本配置,基于xml)

    spring教程 1 1 容器概述1 1 1 配置元数据1 1 2 容器的实例化1 1 3 容器的使用 1 2 bean的概述1 2 1 命名bean1 2 2 实例化Bean 1 3 依赖1 3 1 依赖注入1 3 2 使用 属性1 3
  • 18.5 重载全局new、delete、定位new及重载等

    一 xff1a 重载全局operator new和operator delete操作符 span class token macro property span class token directive hash span span cl
  • java进程占用CPU过高常见的两种情况及分析定位

    java进程爆cpu的快速定位 1 背景 在程序开发的过程中 xff0c 难免遇到进程占用cpu过高 xff08 现网居多 开发环境 xff09 的情况 xff0c 现网出现这种情况就需要及时的能定位到问题 xff0c 快速解决 xff0c
  • 【Android ViewBinding】内存泄露

    场景 在MainActivity中分别加载两个Fragment处理业务 首先触发加载SecondFragment xff1a MainActivity触发 supportFragmentManager commit add R id con
  • Shell小脚本实现一键关机/重启虚拟机

    利用Shell脚本实现一键关机 重启虚拟机 xff0c 解决每次虚拟机关机或重启都需要手动一个个关机或重启的烦恼 xff01 1 脚本一 xff1a shut sh span class token comment bin bash spa
  • LAMP环境搭建

    前言 一 在虚拟机上安装Linux系统 二 安装Apache 1 下载好后 xff0c 看了看版本 xff0c 不是太老 xff0c 就没有继续安装 2 开启Apache服务 3 设置Apache开机启动服务 4 尝试一下是否启动了服务 x
  • 小程序跳坑之安卓真机不能访问服务器的问题

    因为一项目 xff0c 有几个页面都需要访问服务器 xff0c 从服务器上下载数据 xff0c 在苹果和开发者工具上都运行完美 xff0c 唯独一款安卓手机 xff0c 访问不了 xff0c 经测试 xff0c 发现是汉字编码问题 xff0
  • python Tkinter 界面button调用多进程函数,弹出多个相同界面

    这是我的界面button command的函数start simulate 这是我的多进程函数 xff1a 点击之后 xff0c 弹出多个相同界面 把调用多进程的函数在 if name 61 61 39 main 39 这里调用就不会出现多
  • python入门之if-else语句

    文章目录 一 if语句二 elif语句三 if嵌套语句四 else语句1五 else语句2六 if else语句举例1七 if else语句举例2 一 if语句 span class token keyword if span False
  • Ubuntu 16.04 远程桌面

    1 安装xrdp sudo apt get install xrdp 2 安装vnc4server 我这里是安装xrdp的时候自动安装的 我看网上很多说是需要单独安装的 3 安装xfce4 sudo apt get install xubu
  • GitLab端口冲突 解决办法

    访问gitlab xff0c 出现 xff1a 502 GitLab在使用的过程中 xff0c 会开启80端口 xff0c 如果80端口被其他的应用程序占用 xff0c 则GitLab的该项服务不能使用 xff0c 所以访问GitLab会失
  • Android开发 之 确认凭证

    确认凭证 主要目的 xff1a 设置不用验证时间 设置为30秒 xff0c 当超过30秒后则需要重新验证身份才能操作 您的应用可以根据用户在多久之前最后一次解锁设备来验证其身份 此功能让用户不必费心记忆应用特定密码 xff0c 您也无需实现