PHP 和 Android 密钥库加密/解密

PHP and Android Keystore encryption / decryption

几个小时以来,我一直在尝试获取此信息,但我找不到问题所在。我正在使用我制作的 php RESTful API 来使用非对称加密来加密数据。

首先,我通过将用户的 public 密钥导出到 android:

来将其保存在服务器中
fun exportPublicKey() : String {
        val publicKey = getPublicKey()
        return android.util.Base64.encodeToString(
            publicKey!!.encoded,
            android.util.Base64.NO_WRAP
        )
    }

这允许我在 PHP 服务器中执行此操作:

$public_key_core = $_POST["public_key"];
$public_key = "-----BEGIN PUBLIC KEY-----\n" . $public_key_core . "\n-----END PUBLIC KEY-----";

我不确定这是正确的方法,但 openssl 似乎“可以”使用该密钥?

然后我使用这两个密钥在本地测试了我的密钥库,使用此代码它工作得很好:

加密:

fun encryptAsymmetricData(data: String, usePrivateKey : Boolean = true): ByteArray {
        val cipher : Cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding")
        val encryptedBytes: ByteArray
        if (usePrivateKey){
            cipher.init(Cipher.ENCRYPT_MODE, getPrivateKey())
            encryptedBytes = cipher.doFinal(data.toByteArray(Charsets.UTF_8))
        } else {
            cipher.init(Cipher.ENCRYPT_MODE, getPublicKey())
            encryptedBytes= cipher.doFinal(data.toByteArray(Charsets.UTF_8))
        }
        return encryptedBytes
    }

解密:

fun decryptAsymmetricData(data: ByteArray): String{
        val cipher : Cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding")

        cipher.init(Cipher.DECRYPT_MODE, getPrivateKey())
        return cipher.doFinal(data).toString(Charsets.UTF_8)
    }

使用它是有效的,因为我对 encryptData 结果执行了“.toByteArray(Charsets.UTF_8)”。 现在问题来了,我使用 base64 编码并执行以下操作以在 PHP:

中加密
openssl_public_encrypt($token->token, $encrypted_token, $user->public_key);
openssl_public_encrypt($user->id, $encrypted_id, $user->public_key);
[...]
'encrypted_user_id' => base64_encode($encrypted_id),
'encrypted_token' => base64_encode($encrypted_token)

但是当我尝试在 Android 中解密时,我遇到了由以下代码引起的异常“javax.crypto.IllegalBlockSizeException”:

val tokenBA = String(getDecoder().decode(this.encryptedToken), Charsets.UTF_8).toByteArray(Charsets.UTF_8)
val userIDBA = String(getDecoder().decode(this.encryptedUserId), Charsets.UTF_8).toByteArray(Charsets.UTF_8)
val token = App.encryptionController.decryptAsymmetricData(tokenBA)
val userID = App.encryptionController.decryptAsymmetricData(userIDBA)

(逻辑是,我在 PHP 中使用 base64 发回我的数据,所以我在 Android 中将其转换为 UTF8,然后获取关联的 ByteArray 来解密它?)

我知道加密在“本地”中有效,但在同时使用 PHP 和 KeyStore 时无效,所以我猜问题要么来自 PHP 加密,要么来自我尝试在 android 中解密它的方式,但我似乎找不到什么问题,你们能帮我吗?

提前致谢!

好的,在搜索并确定问题不是存储在 PHP 服务器中的 public 密钥之后,我找到了答案。这是由于在应用程序中将“base64”字符串转换为实际的ByteArray 的方式造成的。这有效:

val token = App.encryptionController.decryptAsymmetricData(getDecoder().decode(encryptedToken))
val userID = App.encryptionController.decryptAsymmetricData(getDecoder().decode(encryptedUserId))

这之所以有效,是因为我在服务器中执行了“base64_encode”,出于某些(不好的)原因,我认为需要返回到 UTF8 才能在应用程序中获取 ByteArray。