【译】Android中的安全数据-初始化向量
目录
- 初始化向量
- 默认值
- 自订值
- 空值
- 随机加密
- 使用范例
- 下一步是什么
- 安全提示
初始化向量
初始化向量是加密原语的固定大小输入。通常要求它是随机或伪随机的。IV的重点是允许使用相同的密钥来加密几个不同的消息。
在大多数提供程序(包括提供程序和提供程序)中,块算法模式(如CBC
中的AES
)都是必需的。AndroidKeyStore
BC
在API 18上,BC
如果在解密过程中未指定IV,则使用默认Java的提供程序密钥Cipher
将落入IllegalArgumentException
:
在具有AndroidKeyStore
提供者密钥的API 23上,InvalidKeyException
将引发:
<span style="color:#292929">InvalidKeyException:解密时需要IV。使用IvParameterSpec或AlgorithmParameters提供它。</span>
默认值
实现初始化向量支持的最简单方法是使用由密码在加密过程中生成的字节数组数据。可以使用以下cipher.getIV()
方法进行检索:
cipher.init(Cipher.ENCRYPT_MODE,key)
val iv = cipher.iv //返回自动生成的IV值...
//使用密码加密数据
...
//使用密码加密数据
注意,默认值是在Cipher初始化期间生成的,因此
cipher.init()
必须首先调用它,否则cipher.getIv()
将返回空数据。
然后,在解密期间,使用IvParameterSpec
根据生成的IV
值创建的Cipher进行初始化:
val ivSpec = IvParameterSpec(iv)
cipher.init(Cipher.DECRYPT_MODE,key,ivSpec)...
//使用IV初始化的Cipher解密数据
...
//使用IV初始化的Cipher解密数据
像Salt值一样,初始化向量可以与加密数据一起存储在公共存储中。
存储IV
数据的一种可能方法是将数据添加到加密结果中:
并在解密之前根据加密数据进行解析:
完整的源代码在这里。
自订值
正如Dorian Cussen在其博客中提到的IV
,由提供的默认值Cipher
主要取决于Provider的实现。
未实现时可能会遇到这种情况cipher.getIV()
-返回“空”或null
数组。
为了安全起见并避免此类不愉快的时刻,请使用SecureRandom
class 明确声明一个初始化向量。
要创建自定义IV
值,请使用类中的nextBytes(byte[] key)
方法SecureRandom
:
<span style="color:#292929">val iv = ByteArray(ivLength)
SecureRandom()。nextBytes(iv)</span>
在ivLength
依赖于操作模式。对于大多数模式,包括CBC,IV必须与其中的块具有相同的长度 。
AES算法使用128位块,因此初始化矢量的长度等于128位(
ivLength = 16// bytes
)。
生成自定义IV值时,只需Cipher
使用它初始化实例:
<span style="color:#292929">cipher.init(Cipher.ENCRYPT_MODE,密钥,IvParameterSpec(iv))
cipher.init(Cipher.DECRYPT_MODE,密钥,IvParameterSpec(iv))</span>
注意,生成的值必须被传递到init()
用于方法既加密和解密模式。
空值
可能(但不建议)作弊Cipher
。无需在加密之前每次都生成新的随机初始化向量数据,然后在解密之前进行保存和解析,而是将IV作为数组初始化一次,具有固定长度的静态值,并且可以随时随地使用:
//创建一个16字节的数组,填充为0 [0,0,0,0 ..0]
val iv = ByteArray(16)//在加密和解密期间将此数组用作IV数据
cipher.init(Cipher.ENCRYPT_MODE,key,IvParameterSpec(iv))
cipher.init(Cipher.DECRYPT_MODE,key,IvParameterSpec(iv))
//在加密和解密期间将此数组用作IV数据
cipher.init(Cipher.ENCRYPT_MODE,key,IvParameterSpec(iv))
cipher.init(Cipher.DECRYPT_MODE,key,IvParameterSpec(iv))
请记住,这种实现扼杀了IV的本质。
随机加密
为了保护用户数据免于使用不正确的(不是随机的或空的)IV,默认情况下,AndroidKeyStore
Provider不允许使用自定义IV值:
val iv = ByteArray(16)
cipher.init(Cipher.ENCRYPT_MODE,key,IvParameterSpec(iv))//将抛出InvalidAlgorithmParameterException:调用者提供的IV //不允许
cipher.doFinal(data.toByteArray())
//将抛出InvalidAlgorithmParameterException:调用者提供的IV //不允许
cipher.doFinal(data.toByteArray())
在API 23上,该setRandomizedEncryptionRequired
方法已添加到KeyGenParameterSpec
类中,该方法应允许您控制IV是否可以自定义。从文档:
设置是否必须将使用此密钥进行的加密充分随机化,以便每次都为相同的明文生成不同的密文。
…
当需要IND-CPA时:在使用IV的块模式(例如GCM,CBC和CTR)中,加密时将拒绝调用方提供的IV,以确保仅使用随机IV。
val builder = KeyGenParameterSpec.Builder()//强制仅使用由IV生成的默认生成。
// 默认值。
builder.setRandomizedEncryptionRequired(true)//启用自定义生成的IV。
//不起作用。
builder.setRandomizedEncryptionRequired(false)
//强制仅使用由IV生成的默认生成。
// 默认值。
builder.setRandomizedEncryptionRequired(true)//启用自定义生成的IV。
//不起作用。
builder.setRandomizedEncryptionRequired(false)
但它不起作用(至少对于AES
和CBC
)。即使在禁用随机化之后,Cipher
仍然会崩溃InvalidAlgorithmParameterException
并继续需要默认初始化向量。
使用范例
让我们使用带有初始化矢量的对称AES密钥对消息进行加密和解密:
完整的源代码在这里。
【译】Android中的安全数据-初始化向量相关推荐
- Android中使用的数据单位
Android中使用的数据单位 px(Pixels,像素):对应屏幕上的实际像素点. in(Inches,英寸):屏幕物理长度单位. mm(Millimeters,毫米):屏幕物理长度单位. pt(P ...
- Android中清除应用数据的方法
Android 中应用的数据分为内置储存的和外置储存,默认是保存在内置储存的,所以一般清除内置储存的就行了.使用这个工具类: import java.io.File;public class Data ...
- Android中突发情况数据的保存
Android中突发情况数据的保存 本文原创,转载请获得本人准许. 写在前面: 在我们的APP使用的过程中,总有可能出现各种手滑.被压在后台.甚至突然被杀死的情况.所以对APP中一些临时数据或关键持久 ...
- 【译】Android中的安全数据— Android中的加密(第2部分)
目录 锁屏 选择一个钥匙 密钥存储 密钥生成 密钥管理 加密与解密 使用范例 下一步是什么 安全提示 锁屏 如果要保护数据,请保护设备. 为了更加安全,在提供对任何应用程序功能的访问权限之前,我们可以 ...
- 【译】Android中的安全数据— Android中的加密(第1部分)
目录 Java密码体系结构 Android Key Store 样例项目 下一步是什么 安全提示 Java密码体系结构 Android建立在Java密码体系结构(JCA)的基础上,该体系结构提供了用于 ...
- android https详解,如何使用HTTPS和HTTP来解析Android中的JSON数据?
我跟随this到Parse Json在Android中 我用HttpData处理程序成功完成了它. 在这里,我成功将数据发布到服务器并获得响应.. 现在我想在HTTPS的一部分中使用它. 可以任何人建 ...
- android布局添加布局,Android中添加布局和初始化布局总结
在android中布局很重要,下面总结下布局的三种形式 ①.在Activity的onCreate()方法中进行添加比如:setContentView(R.layout.activity_main); ...
- Android中wifi与数据流量的切换监听
最近在做一个wifi和移动数据的监控功能,来来回回折腾了一阵子,这个模块的主要功能是监听整个APP的wifi与数据流量的切换,让用户使用专用流量,而不是用wifi,给一个弹窗,点击确认,自动切换数据流 ...
- android清除缓存有哪些,Android中的清除数据和清除缓存有什么区别,它们分别清除了哪些文件...
清除数据和清除缓存的区别 反射调用系统隐藏接口,需要准备的东西: 一.在AndroidManifest.xml中的manifest标签下添加声明 android:sharedUserId=" ...
最新文章
- Android 使用ContentProvider(内容提供者)查询手机联系
- JAVA lock 原理讲解
- knime如何连接mysql_knime怎么连接MySQL?
- numpy T、transpose()函数、swapaxes()函数
- fg、bg、jobs、、ctrl + z
- 农村结婚彩礼礼金要三斤三两的百元大钞,这大概有多少钱?
- android adb命令使用
- C#获取堆栈信息,输出文件名、行号、函数名、列号等
- [2018.10.18 T3] 小 G 的线段树
- Windows华丽变身MAC OS X
- ESP32-CAM + micropython学习笔记
- ListView 控件与 ImageList 控件
- 之前安装过Multisim14,再次安装失败的解决方法
- 国产CI520 13.56MHz非接触式读写器NFC读卡芯片替代CV520
- unity不规则点击_【Unity游戏开发】UGUI不规则区域点击的实现
- 天池龙珠训练营Python_Task2: 数据结构_(4)字典
- 【分布式事务】如何基于消息中间件实现分布式事务?万字长文给你答案!!
- 一文看尽CES Asia:大变革下的汽车与全面AI化的智能家居
- 【容器】kubectl|K8S常用命令总结|crictl管理命令
- 2019年机器学习/ 深度学习热门论文集锦