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

    技术2022-07-12  89

    目录

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

    按键大小

    到目前为止,我们已经尝试加密小的“ 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+获得。并且没有太多选择可以逃脱:

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

    我知道您对第二种选择的想法:“但是我们已经在使用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_MODE和wrap()方法。要解密密钥,请使用UNWRAP_MODE和unwrap()方法。

     

    完整的源代码在这里。

    使用范例

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

     

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

     

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

     

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

    完整的源代码在这里。

    Processed: 0.015, SQL: 9