【译】Android中的安全数据-初始化向量
目錄
- 初始化向量
- 默認(rèn)值
- 自訂值
- 空值
- 隨機(jī)加密
- 使用范例
- 下一步是什么
- 安全提示
初始化向量
初始化向量是加密原語的固定大小輸入。通常要求它是隨機(jī)或偽隨機(jī)的。IV的重點(diǎn)是允許使用相同的密鑰來加密幾個(gè)不同的消息。
在大多數(shù)提供程序(包括提供程序和提供程序)中,塊算法模式(如CBC中的AES)都是必需的。AndroidKeyStoreBC
在API 18上,BC如果在解密過程中未指定IV,則使用默認(rèn)Java的提供程序密鑰Cipher將落入IllegalArgumentException:
?
在具有AndroidKeyStore提供者密鑰的API 23上,InvalidKeyException將引發(fā):
<span style="color:#292929">InvalidKeyException:解密時(shí)需要IV。使用IvParameterSpec或AlgorithmParameters提供它。</span>默認(rèn)值
實(shí)現(xiàn)初始化向量支持的最簡(jiǎn)單方法是使用由密碼在加密過程中生成的字節(jié)數(shù)組數(shù)據(jù)。可以使用以下cipher.getIV()方法進(jìn)行檢索:
cipher.init(Cipher.ENCRYPT_MODE,key) val iv = cipher.iv //返回自動(dòng)生成的IV值... //使用密碼加密數(shù)據(jù)... //使用密碼加密數(shù)據(jù)注意,默認(rèn)值是在Cipher初始化期間生成的,因此cipher.init()必須首先調(diào)用它,否則cipher.getIv()將返回空數(shù)據(jù)。
然后,在解密期間,使用IvParameterSpec根據(jù)生成的IV值創(chuàng)建的Cipher進(jìn)行初始化:
val ivSpec = IvParameterSpec(iv) cipher.init(Cipher.DECRYPT_MODE,key,ivSpec)... //使用IV初始化的Cipher解密數(shù)據(jù)... //使用IV初始化的Cipher解密數(shù)據(jù)像Salt值一樣,初始化向量可以與加密數(shù)據(jù)一起存儲(chǔ)在公共存儲(chǔ)中。
存儲(chǔ)IV數(shù)據(jù)的一種可能方法是將數(shù)據(jù)添加到加密結(jié)果中:
并在解密之前根據(jù)加密數(shù)據(jù)進(jìn)行解析:
完整的源代碼在這里。
自訂值
正如Dorian Cussen在其博客中提到的IV,由提供的默認(rèn)值Cipher主要取決于Provider的實(shí)現(xiàn)。
未實(shí)現(xiàn)時(shí)可能會(huì)遇到這種情況cipher.getIV()?-返回“空”或null數(shù)組。
為了安全起見并避免此類不愉快的時(shí)刻,請(qǐng)使用SecureRandomclass?明確聲明一個(gè)初始化向量。
要?jiǎng)?chuàng)建自定義IV值,請(qǐng)使用類中的nextBytes(byte[] key)方法SecureRandom:
<span style="color:#292929">val iv = ByteArray(ivLength) SecureRandom()。nextBytes(iv)</span>在ivLength依賴于操作模式。對(duì)于大多數(shù)模式,包括CBC,IV必須與其中的塊具有相同的長度?。
AES算法使用128位塊,因此初始化矢量的長度等于128位(ivLength = 16// bytes)。
生成自定義IV值時(shí),只需Cipher使用它初始化實(shí)例:
<span style="color:#292929">cipher.init(Cipher.ENCRYPT_MODE,密鑰,IvParameterSpec(iv)) cipher.init(Cipher.DECRYPT_MODE,密鑰,IvParameterSpec(iv))</span>注意,生成的值必須被傳遞到init()用于方法既加密和解密模式。
空值
可能(但不建議)作弊Cipher。無需在加密之前每次都生成新的隨機(jī)初始化向量數(shù)據(jù),然后在解密之前進(jìn)行保存和解析,而是將IV作為數(shù)組初始化一次,具有固定長度的靜態(tài)值,并且可以隨時(shí)隨地使用:
//創(chuàng)建一個(gè)16字節(jié)的數(shù)組,填充為0 [0,0,0,0 ..0] val iv = ByteArray(16)//在加密和解密期間將此數(shù)組用作IV數(shù)據(jù) cipher.init(Cipher.ENCRYPT_MODE,key,IvParameterSpec(iv)) cipher.init(Cipher.DECRYPT_MODE,key,IvParameterSpec(iv))//在加密和解密期間將此數(shù)組用作IV數(shù)據(jù) cipher.init(Cipher.ENCRYPT_MODE,key,IvParameterSpec(iv)) cipher.init(Cipher.DECRYPT_MODE,key,IvParameterSpec(iv))請(qǐng)記住,這種實(shí)現(xiàn)扼殺了IV的本質(zhì)。
隨機(jī)加密
為了保護(hù)用戶數(shù)據(jù)免于使用不正確的(不是隨機(jī)的或空的)IV,默認(rèn)情況下,AndroidKeyStoreProvider不允許使用自定義IV值:
val iv = ByteArray(16) cipher.init(Cipher.ENCRYPT_MODE,key,IvParameterSpec(iv))//將拋出InvalidAlgorithmParameterException:調(diào)用者提供的IV //不允許 cipher.doFinal(data.toByteArray())//將拋出InvalidAlgorithmParameterException:調(diào)用者提供的IV //不允許 cipher.doFinal(data.toByteArray())在API 23上,該setRandomizedEncryptionRequired方法已添加到KeyGenParameterSpec類中,該方法應(yīng)允許您控制IV是否可以自定義。從文檔:
設(shè)置是否必須將使用此密鑰進(jìn)行的加密充分隨機(jī)化,以便每次都為相同的明文生成不同的密文。
…
當(dāng)需要IND-CPA時(shí):在使用IV的塊模式(例如GCM,CBC和CTR)中,加密時(shí)將拒絕調(diào)用方提供的IV,以確保僅使用隨機(jī)IV。
但它不起作用(至少對(duì)于AES和CBC)。即使在禁用隨機(jī)化之后,Cipher仍然會(huì)崩潰InvalidAlgorithmParameterException并繼續(xù)需要默認(rèn)初始化向量。
使用范例
讓我們使用帶有初始化矢量的對(duì)稱AES密鑰對(duì)消息進(jìn)行加密和解密:
完整的源代碼在這里。
總結(jié)
以上是生活随笔為你收集整理的【译】Android中的安全数据-初始化向量的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: mysql门派年龄最大的人_目前活着年龄
- 下一篇: 电路 晶振频率_都说晶振是电路的心脏,你