Javax.crypto.BadPaddingException, хотя размер блока правильный (кратный 16)JAVA

Программисты JAVA общаются здесь
Ответить Пред. темаСлед. тема
Anonymous
 Javax.crypto.BadPaddingException, хотя размер блока правильный (кратный 16)

Сообщение Anonymous »

Я столкнулся с этой проблемой при попытке создать шифрование для Preference DataStore. При попытке расшифровать сообщение я получаю это исключение javax.crypto.BadPaddingException

Код: Выделить всё

import android.security.keystore.KeyGenParameterSpec
import android.security.keystore.KeyProperties
import android.util.Base64
import android.util.Log
import java.security.KeyStore
import javax.crypto.Cipher
import javax.crypto.KeyGenerator
import javax.crypto.SecretKey
import javax.crypto.spec.IvParameterSpec

class CryptoManager {
private val keyStore = KeyStore.getInstance("AndroidKeyStore").apply {
load(null)
}

companion object {
private const val ALGORITHM = KeyProperties.KEY_ALGORITHM_AES
private const val BLOCK_MODE = KeyProperties.BLOCK_MODE_CBC
private const val PADDING = KeyProperties.ENCRYPTION_PADDING_PKCS7
private const val TRANSFORMATION = "$ALGORITHM/$BLOCK_MODE/$PADDING"
}

private val encryptCipher get() = Cipher.getInstance(TRANSFORMATION).apply {
init(Cipher.ENCRYPT_MODE, getKey())
}

private fun getDecryptCipherForIv(iv: ByteArray): Cipher {
return Cipher.getInstance(TRANSFORMATION).apply {
init(Cipher.DECRYPT_MODE, getKey(), IvParameterSpec(iv))
}
}

private fun getKey(): SecretKey {
val existingKey = keyStore.getEntry("myAppSecret", null) as? KeyStore.SecretKeyEntry
return existingKey?.secretKey ?: createKey()
}

private fun createKey(): SecretKey {
return KeyGenerator.getInstance(ALGORITHM).apply {
init(
KeyGenParameterSpec.Builder(
"myAppSecret",
KeyProperties.PURPOSE_ENCRYPT or KeyProperties.PURPOSE_DECRYPT
)
.setBlockModes(BLOCK_MODE)
.setEncryptionPaddings(PADDING)
.setUserAuthenticationRequired(false)
.setRandomizedEncryptionRequired(true)
.build()
)
}.generateKey()
}

private fun getSizeBytes(size: Int): ByteArray {
return byteArrayOf(
(size shr 24).toByte(),
(size shr 16).toByte(),
(size shr 8).toByte(),
size.toByte()
)
}

private fun getSizeFromBytes(bytes: ByteArray): Int {
return (bytes[0].toInt() shl 24) or
((bytes[1].toInt() and 0xFF) shl 16) or
((bytes[2].toInt() and 0xFF) shl 8) or
(bytes[3].toInt() and 0xFF)
}

fun encrypt(bytes: ByteArray): ByteArray {
val encrypted = encryptCipher.doFinal(bytes)
val sizeBytes = getSizeBytes(encrypted.size)
val iv = encryptCipher.iv

Log.d("myDebug", "encrypt iv: ${iv.map { it.toInt().toByte() }.joinToString(" ")}")

return Base64.encode(byteArrayOf(encryptCipher.iv.size.toByte()) +
iv +
sizeBytes +
encrypted,
Base64.DEFAULT)

}

fun decrypt(bytes64: ByteArray): ByteArray {

// ByteArray should look like IV_SIZE | IV | MESSAGE_SIZE_BYTES | MESSAGE
val bytes = Base64.decode(bytes64, Base64.DEFAULT)

Log.d("myDebug", "decrypt bytes: ${bytes.map { it.toInt().toByte() }.joinToString(" ")}")

// Pointer for moving, and extracting data from ByteArray
var pointer = 0

val ivSize = bytes[pointer++].toInt()

val iv = bytes.sliceArray(pointer until ivSize + pointer)

Log.d("myDebug", "iv: ${iv.map { it.toInt().toByte() }.joinToString(" ")}")

pointer += ivSize

// size of the message is coded over 4 bytes (int)
val messageSize = getSizeFromBytes(bytes.sliceArray(pointer until pointer + 4))

Log.d("myDebug", "messageSize: $messageSize")

pointer += 4

val encryptedMessage = bytes.sliceArray(pointer until pointer + messageSize)
Log.d("myDebug", "message: ${encryptedMessage.map { it.toInt().toByte() }.joinToString("  ")}")
Log.d("myDebug", "extracted message size: ${encryptedMessage.size}")

return getDecryptCipherForIv(iv).doFinal(encryptedMessage)
}
}
После извлечения сообщения я вижу, что оно дополняется и извлекается правильно — кратно 16. Я что-то упустил? В чем проблема с этим кодом? Я оставил несколько файлов Log.d на случай, если кто-нибудь захочет его запустить.

Код: Выделить всё

javax.crypto.BadPaddingException at android.security.keystore2.AndroidKeyStoreCipherSpiBase.engineDoFinal(AndroidKeyStoreCipherSpiBase.java:624) at javax.crypto.Cipher.doFinal(Cipher.java:2056)
Спасибо, что уделили время

Подробнее здесь: https://stackoverflow.com/questions/790 ... ultiple-of
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение
  • Javax.crypto.BadPaddingException, хотя размер блока правильный (кратный 16)
    Anonymous » » в форуме JAVA
    0 Ответы
    18 Просмотры
    Последнее сообщение Anonymous
  • Javax.crypto.BadPaddingException, хотя размер блока правильный (кратный 16)
    Anonymous » » в форуме Android
    0 Ответы
    23 Просмотры
    Последнее сообщение Anonymous
  • Javax.crypto.BadPaddingException, хотя размер блока правильный (кратный 16)
    Anonymous » » в форуме JAVA
    0 Ответы
    22 Просмотры
    Последнее сообщение Anonymous
  • Javax.crypto.BadPaddingException, хотя размер блока правильный (кратный 16)
    Anonymous » » в форуме Android
    0 Ответы
    14 Просмотры
    Последнее сообщение Anonymous
  • Javax.crypto.BadPaddingException, хотя размер блока правильный (кратный 16)
    Anonymous » » в форуме Android
    0 Ответы
    9 Просмотры
    Последнее сообщение Anonymous

Вернуться в «JAVA»