Android的KeyStore保护数据

有知友问我keystore的知识,我们先看谷歌文档对安卓中keystore的解释:

Android Keystore系统可让您将加密密钥存储在容器中,以使其更难从设备中提取。一旦密钥进入密钥库,就可以将其用于加密操作,而密钥材料仍不可导出。而且,它提供了限制何时和如何使用密钥的功能,例如要求用户进行身份验证才能使用密钥,或者限制仅在某些加密模式下使用密钥。

让我们先清除一些有关Android Keystore系统的知识。密钥库不一定只用于密码,它可以用于任何敏感数据,这样做的方式使攻击者或恶意/未经授权的软件很难从我们这里获取此信息。

简单来说:应用程序只能编辑,保存和检索自己的密钥。

这个概念很简单,但功能强大。该应用将生成或接收私钥-公钥对,然后将其存储在Android Keystore系统中。

然后,在将公用密钥存储在特定于应用程序的文件夹中之前,可以使用公用密钥对应用程序秘密进行加密,并在需要时使用专用密钥对相同信息进行解密。

同样是这样几个步骤:

  • 创建秘钥
  • 加密数据
  • 解密数据

1、创建秘钥:

在开始加密过程之前,我们需要为要用来加密/解密数据的别名提供一个名称。可以是任何字符串。只要不是一个空的。别名是生成的密钥将出现在Android KeyStore中的条目的名称。

final KeyGenerator keyGenerator = KeyGenerator
        .getInstance(KeyProperties.KEY_ALGORITHM_AES, "AndroidKeyStore");

此密钥生成器的算法将是AES,并且我们要将密钥/数据保存在AndroidKeyStore中。

那么这个KeyGenParameterSpec到底是什么?

您可以将KeyGenParameterSpec视为我们将要生成的键的属性。例如,假设我们希望密钥在一定时间后过期,这就是我们要指定的地方。

他是我们的KeyGenParameterSpec。

final KeyGenerator keyGenerator = KeyGenerator
        .getInstance(KeyProperties.KEY_ALGORITHM_AES, ANDROID_KEY_STORE);
final KeyGenParameterSpec keyGenParameterSpec = new KeyGenParameterSpec.Builder(alias,
        KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT)
        .setBlockModes(KeyProperties.BLOCK_MODE_GCM)
       .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE)
        .build();

第一件事是我们传入我们要使用的别名。接下来,我们指定目的,即加密解密数据。

由于我们使用的是“ AES / GCM / NoPadding”转换算法,因此我们还告诉KeyGenParameterSpec应该使用的填充类型。

2、加密数据

final KeyGenerator keyGenerator = KeyGenerator
        .getInstance(KeyProperties.KEY_ALGORITHM_AES, ANDROID_KEY_STORE);

final KeyGenParameterSpec keyGenParameterSpec = new KeyGenParameterSpec.Builder(alias,
        KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT)
        .setBlockModes(KeyProperties.BLOCK_MODE_GCM)
       .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE)
        .build();

keyGenerator.init(keyGenParameterSpec);
final SecretKey secretKey = keyGenerator.generateKey();

final Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
cipher.init(Cipher.ENCRYPT_MODE, secretKey);

现在我们有了密钥,我们将使用它来初始化我们的cipher对象,这将负责实际的加密。我们告诉Cipher我们将要使用的加密转换的类型,我们指定我们现在要进行加密,然后传入secretKey进行加密。

final KeyGenerator keyGenerator = KeyGenerator
        .getInstance(KeyProperties.KEY_ALGORITHM_AES, ANDROID_KEY_STORE);

final KeyGenParameterSpec keyGenParameterSpec = new KeyGenParameterSpec.Builder(alias,
        KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT)
        .setBlockModes(KeyProperties.BLOCK_MODE_GCM)
        .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE)
        .build();

keyGenerator.init(keyGenParameterSpec);
final SecretKey secretKey = keyGenerator.generateKey();

final Cipher cipher = Cipher.getInstance(TRANSFORMATION);
cipher.init(Cipher.ENCRYPT_MODE, secretKey);

iv = cipher.getIV();

encryption = cipher.doFinal(textToEncrypt.getBytes("UTF-8"));

接下来,我们获取解密所需的密码初始化向量(IV)的引用,并使用doFinal(textToEncrypt)完成加密。doFinal方法返回一个字节数组,它是实际的加密文本。

3、解密数据

先获取keystore实例:

keyStore =getInstance(“ AndroidKeyStore ”); 
keyStore.load(null);

获取secretKey。

keyStore = KeyStore.getInstance("AndroidKeyStore");
keyStore.load(null);
final KeyStore.SecretKeyEntry secretKeyEntry = (KeyStore.SecretKeyEntry) keyStore
        .getEntry(alias, null);

final SecretKey secretKey = secretKeyEntry.getSecretKey();

我们需要一个GCMParameterSpec指定身份验证标签的长度,并传入我们在加密过程中较早时获取的IV来解密。

keyStore = KeyStore.getInstance("AndroidKeyStore");
keyStore.load(null);
final KeyStore.SecretKeyEntry secretKeyEntry = (KeyStore.SecretKeyEntry) keyStore
        .getEntry(alias, null);

final SecretKey secretKey = secretKeyEntry.getSecretKey();
final Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
final GCMParameterSpec spec = new GCMParameterSpec(128, encryptionIv);
cipher.init(Cipher.DECRYPT_MODE, secretKey, spec);

然后就结束了,总的来说,运用起来是十分方便的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值