繁体   English   中英

PHP和Android Keystore加密/解密

[英]PHP and Android Keystore encryption / decryption

几个小时以来,我一直在努力解决这个问题,但我找不到问题所在。 我正在使用 php RESTful API 来使用非对称加密来加密数据。

首先,我通过在 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)

(逻辑是,我用base64发回我在PHP的数据,所以我在Android把它转换成UTF8,然后得到关联的ByteArray来解密?)

我知道加密在“本地”工作,但在同时使用 PHP 和 KeyStore 时不起作用,所以我猜问题要么来自 PHP 加密,要么来自我尝试在 android 中解密它的方式,但我可以好像发现了什么问题,请你们帮帮我好吗?

提前谢谢你!

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

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM