@@ -23,7 +23,8 @@ class IterableDataEncryptor {
23
23
private const val TRANSFORMATION_LEGACY = " AES/CBC/PKCS5Padding"
24
24
private const val ITERABLE_KEY_ALIAS = " iterable_encryption_key"
25
25
private const val GCM_TAG_LENGTH = 128
26
- private const val IV_LENGTH = 16
26
+ private const val GCM_IV_LENGTH = 12
27
+ private const val CBC_IV_LENGTH = 16
27
28
private val TEST_KEYSTORE_PASSWORD = " test_password" .toCharArray()
28
29
29
30
private val keyStore: KeyStore by lazy {
@@ -132,11 +133,12 @@ class IterableDataEncryptor {
132
133
encryptLegacy(data)
133
134
}
134
135
135
- // Combine isModern flag, IV, and encrypted data
136
- val combined = ByteArray (1 + encryptedData.iv.size + encryptedData.data.size)
136
+ // Combine isModern flag, IV length, IV , and encrypted data
137
+ val combined = ByteArray (1 + 1 + encryptedData.iv.size + encryptedData.data.size)
137
138
combined[0 ] = if (encryptedData.isModernEncryption) 1 else 0
138
- System .arraycopy(encryptedData.iv, 0 , combined, 1 , encryptedData.iv.size)
139
- System .arraycopy(encryptedData.data, 0 , combined, 1 + encryptedData.iv.size, encryptedData.data.size)
139
+ combined[1 ] = encryptedData.iv.size.toByte() // Store IV length
140
+ System .arraycopy(encryptedData.iv, 0 , combined, 2 , encryptedData.iv.size)
141
+ System .arraycopy(encryptedData.data, 0 , combined, 2 + encryptedData.iv.size, encryptedData.data.size)
140
142
141
143
return Base64 .encodeToString(combined, Base64 .NO_WRAP )
142
144
} catch (e: Exception ) {
@@ -153,8 +155,9 @@ class IterableDataEncryptor {
153
155
154
156
// Extract components
155
157
val isModern = combined[0 ] == 1 .toByte()
156
- val iv = combined.copyOfRange(1 , 1 + IV_LENGTH )
157
- val encrypted = combined.copyOfRange(1 + IV_LENGTH , combined.size)
158
+ val ivLength = combined[1 ].toInt()
159
+ val iv = combined.copyOfRange(2 , 2 + ivLength)
160
+ val encrypted = combined.copyOfRange(2 + ivLength, combined.size)
158
161
159
162
val encryptedData = EncryptedData (encrypted, iv, isModern)
160
163
@@ -187,16 +190,15 @@ class IterableDataEncryptor {
187
190
}
188
191
189
192
val cipher = Cipher .getInstance(TRANSFORMATION_MODERN )
190
- val iv = generateIV()
191
- val spec = GCMParameterSpec (GCM_TAG_LENGTH , iv)
192
- cipher.init (Cipher .ENCRYPT_MODE , getKey(), spec)
193
+ cipher.init (Cipher .ENCRYPT_MODE , getKey())
194
+ val iv = cipher.iv
193
195
val encrypted = cipher.doFinal(data)
194
196
return EncryptedData (encrypted, iv, true )
195
197
}
196
198
197
199
private fun encryptLegacy (data : ByteArray ): EncryptedData {
198
200
val cipher = Cipher .getInstance(TRANSFORMATION_LEGACY )
199
- val iv = generateIV()
201
+ val iv = generateIV(isModern = false )
200
202
val spec = IvParameterSpec (iv)
201
203
cipher.init (Cipher .ENCRYPT_MODE , getKey(), spec)
202
204
val encrypted = cipher.doFinal(data)
@@ -222,8 +224,9 @@ class IterableDataEncryptor {
222
224
return cipher.doFinal(encryptedData.data)
223
225
}
224
226
225
- private fun generateIV (): ByteArray {
226
- val iv = ByteArray (IV_LENGTH )
227
+ private fun generateIV (isModern : Boolean = false): ByteArray {
228
+ val length = if (isModern) GCM_IV_LENGTH else CBC_IV_LENGTH
229
+ val iv = ByteArray (length)
227
230
SecureRandom ().nextBytes(iv)
228
231
return iv
229
232
}
0 commit comments