AES-шифрование. Различия между PHP и Kotlin \ Java

Существует веб-сайт, который использует 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 для сайта, и я застрял. Я пытаюсь реализовать поведение CryptoJSAES на Kotlin, но это не сработает. Думаю, потому что я не понимаю точно разницу между функциями md5 () и openssl_encrypt () в PHP и Kotlin \ Java

Мой вариант методов:

 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) 

Это работает как-то, но сайт не может получить результат. Заранее благодарим за любые советы

    Наконец, у меня это есть.
    Если вы используете параметр «raw_output» = true в функции md5 () php в Kotlin, вам нужно использовать 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) }