I am trying to make an android application in kotlin, after i save the user info (that i got from my API) in a file on the device i run the method to decrypt it, but it gives me “javax.crypto.BadPaddingException: error:1e000065:Cipher functions:OPENSSL_internal:BAD_DECRYPT” exception. And I can’t figure out why, somebody help?
This is the code of the decryption function:
package com.example.uniapp
import android.annotation.SuppressLint
import android.os.Build
import androidx.annotation.RequiresApi
import java.nio.charset.StandardCharsets
import java.util.Base64
import javax.crypto.Cipher
import javax.crypto.spec.IvParameterSpec
import javax.crypto.spec.SecretKeySpec
object EncryptionUtils {
@SuppressLint("NewApi")
fun decrypt(encryptedText: String, aesKey: String): String {
// Decode the Base64 encoded string
val fullCipher = Base64.getDecoder().decode(encryptedText)
// Create an AES cipher instance
val cipher = Cipher.getInstance("AES/CBC/PKCS5Padding")
val blockSize = cipher.blockSize
// Extract the IV and the actual cipher text
val iv = fullCipher.copyOfRange(0, blockSize)
val cipherBytes = fullCipher.copyOfRange(blockSize, fullCipher.size)
// Setup the key and IV
val keySpec = SecretKeySpec(aesKey.toByteArray(StandardCharsets.UTF_8), "AES")
val ivSpec = IvParameterSpec(iv)
// Initialize the cipher for decryption
cipher.init(Cipher.DECRYPT_MODE, keySpec, ivSpec)
// Perform decryption
val decryptedBytes = cipher.doFinal(cipherBytes)
// Convert decrypted bytes to string
return String(decryptedBytes, StandardCharsets.UTF_8)
}
}
And this is the login activity that calls decryption (it’s not finished)
package com.example.uniapp
import android.content.Intent
import android.os.Build
import android.os.Bundle
import android.widget.Button
import android.widget.EditText
import android.widget.Toast
import androidx.annotation.RequiresApi
import androidx.appcompat.app.AppCompatActivity
import com.example.uniapp.network.NetworkService
import com.example.uniapp.util.EncryptionUtils
import com.example.uniapp.util.FileStorageUtils
import com.example.uniapp.util.GlobalVariables
class LoginActivity : AppCompatActivity() {
private val apiUrl = "${GlobalVariables.apiCommonUrl}users/userinfo"
private val aesKey = "${GlobalVariables.AESKey}" // Replace with your actual key
private lateinit var networkService: NetworkService
@RequiresApi(Build.VERSION_CODES.O)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.login_screen)
networkService = NetworkService(apiUrl)
val usernameEditText = findViewById<EditText>(R.id.usernameField)
val passwordEditText = findViewById<EditText>(R.id.passwordField)
val loginButton = findViewById<Button>(R.id.loginButton)
loginButton.setOnClickListener {
val username = usernameEditText.text.toString()
val password = passwordEditText.text.toString()
loginUser(username, password)
}
}
@RequiresApi(Build.VERSION_CODES.O)
private fun loginUser(username: String, password: String) {
networkService.loginUser(username, password) { success, encryptedUserInfo ->
if (success && encryptedUserInfo != null) {
FileStorageUtils.saveToFile(this, "user_info.txt", encryptedUserInfo)
val intent = Intent(this, HomepageProfessor::class.java)
startActivity(intent)
decryptUserInfo(encryptedUserInfo)
} else {
runOnUiThread {
Toast.makeText(this, "Login failed", Toast.LENGTH_SHORT).show()
}
}
}
}
@RequiresApi(Build.VERSION_CODES.O)
private fun decryptUserInfo(encryptedUserInfo: String) {
val decryptedUserInfo = EncryptionUtils.decrypt(encryptedUserInfo, aesKey)
runOnUiThread {
if (decryptedUserInfo != null) {
Toast.makeText(this, "Decrypted User Info: $decryptedUserInfo", Toast.LENGTH_LONG).show()
} else {
Toast.makeText(this, "Decryption failed", Toast.LENGTH_SHORT).show()
}
}
}
}
The AESKey is of 32 bytes so it is correct, and this code respects the encryption of the API.
New contributor