【译】在Android中保护数据-加密大数据

目录

  • 按键大小
  • 该怎么办
  • 默认提供者
  • 对称键
  • 按键包装
  • 使用范例
  • 下一步是什么
  • 安全提示

按键大小

到目前为止,我们已经尝试加密小的“ Hello World”消息。让我们尝试加密更大的一个,然后再加密250个符号。糟糕,IllegalBlockSizeException

 

 

RSA原为 没有设计 处理大量数据。您只能处理有限长度的消息,这取决于密钥大小。密钥越大,则可以加密越大的消息。

请注意,使用大密钥会增加加密时间,并可能影响应用程序性能。避免在主应用程序线程上进行大数据加密。

在密钥生成过程中,您可以使用setKeySize()方法指定密钥大小:

 

无法在Android Key Store提供程序中的API 18上自定义密钥大小。

如果没有手动设置,将使用默认密钥大小。默认值可能取决于提供商和平台版本。对于RSA密钥,在Android密钥存储提供程序中,它是2048位

支持的RSA密钥大小为:512、768、1024、2048、3072、4096。请在文档中查看有关支持的算法和密钥大小的更多详细信息。


您可以使用一个公式来计算最大RSA消息长度。对于n位RSA密钥(带有PKCS1填充),直接加密适用于任意二进制消息,最高可达:

<span style="color:#292929">floor(n / 8)-11个字节</span>

对于1024位RSA密钥(128个字节),您可以使用最大117个字节的消息。因此,我们可以通过RSA密钥获得的最长消息可以包含最大468字节(使用4096位密钥)。

该怎么办

这里的情况非常糟糕,无法使用非对称密钥,而对称仅可从API 23+获得。并且没有太多选择可以逃脱:

  1. 使用默认的Java提供程序之一创建对称密钥。用它加密/解密消息。然后使用RSA公共密钥对该密钥原始数据进行加密,并将其保存到磁盘中的某个位置。解密时,获取加密的原始密钥数据,使用RSA私钥对其进行解密,然后将其用于消息解密。
  2. 在部件上分离大消息,并分别加密/解密每个部件。

我知道您对第二种选择的想法:“但是我们已经在使用ECB模式,它会自动执行此操作,不是吗?” (请参阅加密,模式和填充)。

不幸的是,即使使用ECB模式(在Android Key Store提供程序实现中),RSA算法也只能处理一个数据块,并且如果消息长于一个块大小,它将崩溃。

要解决此问题,您可以手动分离数据并对其进行处理(模拟ECB模式)。但是同样,RSA不是为此类任务设计的。

将是更安全的继续第一个选项。

您可以在此处检查第二个选项的实现。

默认提供者

我们要做的第一件事是:使用默认的Java提供程序之一生成对称密钥。

android中最常见的默认Java提供BC程序是由流行的第三方Java密码库提供程序Bouncy Castle创建的提供程序的简化版本

 

KeyGenerator类负责对称密钥的生成。使用其getInstance()方法之一创建AES密钥的实例。

您可以通过调用Security.getProviders()方法来获取所有可用的提供程序:

<span style="color:#292929">Security.getProviders()。forEach <strong>{ </strong><em>logi</em>(<strong>it</strong> .name)<strong>}</strong></span>

注意:可用的提供程序可能会因不同的平台和供应商而异。如果您要查找的提供程序在设备上不存在,则可以通过调用以下方法之一来注册自己的(或某些第三方)提供程序:

Security.addProvider(提供者)//这样,您就可以控制
应用程序的首选提供程序。请参见Android中的加密(第2部分)
 Security.insertProviderAt(提供者,位置)//这样,您就可以控制
应用程序的首选提供程序。请参见Android中的加密(第2部分)
 Security.insertProviderAt(提供者,位置)

或者,您可以使用getInstance(algorithm),这将根据您的提供程序列表为您返回最优选的实现。

val keyGenerator = KeyGenerator.getInstance(“ AES”)//提供者列表:
// 1. 1. Android密钥库
// 2.自定义提供者
// 3. BC//如果Android密钥存储区和自定义提供程序不具有AES算法,则将输出BC。
keyGenerator.provider.name//提供者列表:
// 1. 1. Android密钥库
// 2.自定义提供者
// 3. BC//如果Android密钥存储区和自定义提供程序不具有AES算法,则将输出BC。
keyGenerator.provider.name

对称键

基本上,我们没有最多23个API的对称密钥。但是从M开始,我们只能使用Android Key Store提供程序中的一个对称密钥。

 

使用KeyGenerator在对与KeyGenParameterSpec创建一个。同样不要忘记Cipher对称加密需要的转换:

 

完整的源代码在这里。

按键包装

为了保护我们的AES密钥并将其安全地保存在设备的公共持久性存储(例如首选项,文件或数据库)中,我们将使用RSA存储在Android Key Store中的密钥对其进行加密和解密。此过程也称为密钥包装

 

为此,Cipher有单独WRAP_MODEwrap()方法。要解密密钥,请使用UNWRAP_MODEunwrap()方法。

 

完整的源代码在这里。

使用范例

让我们尝试使用新方法对大型邮件进行加密和解密:

 

在M及更高版本上运行,请使用一个对称密钥:

 

在M之前,使用两个非对称和对称密钥:

 

而且这还不够,我们能够加密消息,但不能解密消息。

完整的源代码在这里。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章