AES加密。 PHP和Kotlin \ Java的区别

问题描述 投票:-1回答:1

有一个网站使用CryptoJSAES lib来编码和解码请求。 https://github.com/blocktrail/cryptojs-aes-php/blob/master/src/CryptoJSAES.php

abstract class CryptoJSAES {
    /**
     * @param      $data
     * @param      $passphrase
     * @param null $salt        ONLY FOR TESTING
     * @return string           encrypted data in base64 OpenSSL format
     */
    public static function encrypt($data, $passphrase, $salt = null) {
        $salt = $salt ?: openssl_random_pseudo_bytes(8);
        list($key, $iv) = self::evpkdf($passphrase, $salt);
        $ct = openssl_encrypt($data, 'aes-256-cbc', $key, true, $iv);
        return self::encode($ct, $salt);
    }

    public static function evpkdf($passphrase, $salt) {
        $salted = '';
        $dx = '';
        while (strlen($salted) < 48) {
            $dx = md5($dx . $passphrase . $salt, true);
            $salted .= $dx;
        }
        $key = substr($salted, 0, 32);
        $iv = substr($salted, 32, 16);
        return [$key, $iv];
    }

    public static function encode($ct, $salt) {
        return base64_encode("Salted__" . $salt . $ct);
    }
}

现在我正在为该网站的Android客户端工作,我陷入困境。我正在尝试在Kotlin上实现CryptoJSAES行为,但它不起作用。我想因为我不完全理解PHP和Kotlin \ Java中md5()和openssl_encrypt()函数之间的区别

我的方法变种:

class CryptoJSAES
{

    fun encrypt(data: ByteArray, key: ByteArray, ivs: ByteArray): ByteArray? 
    {
        try {
            val cipher = Cipher.getInstance("AES/CBC/PKCS5Padding")
            val secretKeySpec = SecretKeySpec(key, "AES")
            val finalIvs = ByteArray(16)
            val len = if (ivs.size > 16) 16 else ivs.size
            System.arraycopy(ivs, 0, finalIvs, 0, len)
            val ivps = IvParameterSpec(finalIvs)
            cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, ivps)
            return cipher.doFinal(data)
        } catch (e: Exception) {
            e.printStackTrace()
        }

        return null
    } 

    fun evpkdf(passphrase : String, salt : String = "") : Pair<String, String>{
        var salted = ""
        var dx   = ""
        while (salted.length < 48) {

            dx = MD5Encode(dx + passphrase + salt)!!
            salted += dx
        }
        val key = salted.toString().substring(0, 32)
        val iv = salted.toString().substring(32, 32 + 16)

        return Pair(key, iv)
    }

private fun MD5Encode(sourceString: String): String? {
        try {
            val bytesOfMessage = sourceString.toByteArray(charset("UTF-8"))
            val md = MessageDigest.getInstance("MD5")
            // byte array of md5 hash
            val md5 = md.digest(bytesOfMessage)
            // we convert bytes to hex as php's md5() would do
            val stringBuffer = StringBuffer()
            for (i in md5.indices) {
                stringBuffer.append(Integer.toString((md5[i] and 0xff.toByte()) + 0x100,
                        16).substring(1))
            }
            return stringBuffer.toString()
        } catch (e: Exception) {
        }

        return null
    }
}

使用:

val testText = "Hello"
val password = "password#123456"
val salt = "12345678"

val res = evpkdf(password, salt)

val encryptTextBytes = encrypt(testText.toByteArray(), res.first.toByteArray(), res.second.toByteArray())

Base64.encodeToString(("Salted__"+salt).toByteArray().plus(encryptTextByte), DEFAULT)

它以某种方式工作,但网站无法得到结果。提前感谢任何建议

php android kotlin aes
1个回答
0
投票

最后,我知道了。 如果你在Kotlin的php的md5()函数中使用param“raw_output”= true,你需要使用ByteArrays来获得相同的结果

fun md5_raw(input: ByteArray?): ByteArray {
        var result = input
        if (input != null) {
            val md = MessageDigest.getInstance("MD5") //or "SHA-1"
            md.update(input)

            return md.digest()

        }
        return ByteArray(0)
    }

   fun evpkdf(passphrase : String, salt : String = "") : Pair<ByteArray, ByteArray>{
        var salted : ByteArray = ByteArray(0)
        var dx : ByteArray = ByteArray(0)
        while (salted.size < 48) {

            dx = md5_raw(dx.plus(passphrase.toByteArray()).plus(salt.toByteArray()))
            salted = salted.plus(dx)
        }

        val key = salted.copyOfRange(0, 32)
        val iv = salted.copyOfRange(32, 32 + 16)

        return Pair(key, iv)
    }
© www.soinside.com 2019 - 2024. All rights reserved.