Android — шифрование AES. Различия PHP и Kotlin \ Java

Существует веб-сайт, который использует библиотеку CryptoJSAES для кодирования и декодирования запросов.
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)

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

-1

Решение

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

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]