Wie kann man mcrypt_decrypt ersetzen

Hat von Euch jemand eine Idee wie man das hier (Python)
Column ZToken of the iOS app contains a 96 character token · Issue #75 · rytilahti/python-miio · GitHub

in PHP umsetzt?

PYTHON


from Crypto.Cipher import AES
import binascii
keystring = '00000000000000000000000000000000'
iostoken = '16a935db276e19b1c7bef0739f2deb7d3aca43c5e26a3c6445351cb2fb8495ea0143db63ee66b0cdff9f69917680151e'
key = bytes.fromhex(keystring)
cipher = AES.new(key, AES.MODE_ECB)
token = cipher.decrypt(bytes.fromhex(iostoken[:64]))
print(token)
# Output: b'4a447a41467058496746505541597033'

mit dem Tool

http://aes.online-domain-tools.com/

geht das auch. Die Frage ist nur wie geht das mit PHP ohne weitere Sprachen bzw. externe Lösungen?

Mit der openssl extension sollte das genauso gehen.

PHP: openssl_decrypt - Manual

Tommi

<edit> Sehe gerade das es dafür schon fertige Beispiele ne Seite weiter vorn gibt - siehe KM200 </edit>

Hat jemand vielleicht ein Codebeispiel für ECB s.o. ich bekomme das irgendwie nicht hin das der Code so berechnet wird wie im Python Beispiel.

#13 von Paresy. GGfls musst Du mit dem Padding noch spielen. Siehe dem Link dort

Was heisst denn mit dem Padding spielen? Bei mir kommt jedes mal das gleiche raus.

No Padding


$decryptData = '16a935db276e19b1c7bef0739f2deb7d3aca43c5e26a3c6445351cb2fb8495ea0143db63ee66b0cdff9f69917680151e';
$short_token =  openssl_decrypt($decryptData, 'AES-128-ECB', str_repeat("\0",16), OPENSSL_RAW_DATA|OPENSSL_NO_PADDING); 
var_dump($short_token);

ergibt


string(96) "DQsź0ó_ħãeÏÙÞÍËlsÊæéJ>øÝùc}µ¢xß}Ò%ƒ+ÿ¹ð”Ä{à÷£*üûMØdž1$š*0K¹ñó¯¯Û+9èåõİ‚X’_yÁžM{"

Zero Padding


$decryptData = '16a935db276e19b1c7bef0739f2deb7d3aca43c5e26a3c6445351cb2fb8495ea0143db63ee66b0cdff9f69917680151e';
$decrypt = openssl_decrypt($decryptData, 'AES-128-ECB', str_repeat("\0",16), OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING);
var_dump($decrypt); 

ergibt


string(96) "DQsź0ó_ħãeÏÙÞÍËlsÊæéJ>øÝùc}µ¢xß}Ò%ƒ+ÿ¹ð”Ä{à÷£*üûMØdž1$š*0K¹ñó¯¯Û+9èåõİ‚X’_yÁžM{"

Ich finde den Fehler einfach nicht bzw. was ich anders machen müsste damit das funktioniert.

Rauskommen soll eigentlich


4a447a41467058496746505541597033

Siehe auch
AES Encryption – Easily encrypt or decrypt strings or files

Moin Fonzo!

Probier das mal aus:

<?
$secret = str_repeat("\0",16);

$str = '16a935db276e19b1c7bef0739f2deb7d3aca43c5e26a3c6445351cb2fb8495ea0143db63ee66b0cdff9f69917680151e';
$decrypt = sslDecrypt(hex2bin($str), $secret);
var_dump($decrypt);  


$str = "4a447a41467058496746505541597033";
$encrypt = sslEncrypt($str, $secret);
var_dump($encrypt);
$decrypt = sslDecrypt($encrypt, $secret);
var_dump($decrypt);  


function sslEncrypt($str, $secret)
{
    return openssl_encrypt($str, 'aes-128-ecb', $secret, OPENSSL_RAW_DATA);
}

function sslDecrypt($str, $secret)
{
    return openssl_decrypt($str, 'aes-128-ecb', $secret, OPENSSL_RAW_DATA);
}

?>

Ergibt als Ausgabe:

string(32) "4a447a41467058496746505541597033"
string(48) "©5Û'n±ǾðsŸ-ë}:ÊCÅâj<dE5²û„•êCÛcîf°ÍÿŸi‘v€"
string(32) "4a447a41467058496746505541597033"

Grüße,
Chris

Ja Wahnsinn, manchmal sind es Kleinigkeiten, vielen vielen Dank. Das Entschlüsseln scheint so auch zu funktionieren. Beim Verschlüsseln scheint es aber wohl noch abhängig vom String Probleme zu geben. Hast Du eventuell eine Idee woran das noch liegen könnte?


$ios_token = "16a935db276e19b1c7bef0739f2deb7d3aca43c5e26a3c6445351cb2fb8495ea0143db63ee66b0cdff9f69917680151e"; // python test
$keystring = '00000000000000000000000000000000';
$secret = str_repeat("\0",16); 
$token = "4a447a41467058496746505541597033"; // python test


$decrypt = sslDecrypt(hex2bin($ios_token), $secret); 
var_dump($decrypt);   

$encrypt = sslEncrypt($token, $secret); 
var_dump($encrypt); // raw
$ios_token_b = bin2hex($encrypt);
var_dump($ios_token_b); // string
$decrypt = sslDecrypt($encrypt, $secret); 
var_dump($decrypt); 
$decrypt = sslDecrypt(hex2bin($ios_token_b), $secret); 
var_dump($decrypt);    


function sslEncrypt($str, $secret) 
{ 
    return openssl_encrypt($str, 'aes-128-ecb', $secret, OPENSSL_RAW_DATA); 
} 

function sslDecrypt($str, $secret) 
{ 
    return openssl_decrypt($str, 'aes-128-ecb', $secret, OPENSSL_RAW_DATA); 
}


geht und ergibt


string(32) "4a447a41467058496746505541597033"
string(48) "©5Û'n±ǾðsŸ-ë}:ÊCÅâj<dE5²û„•êCÛcîf°ÍÿŸi‘v€"
string(96) "16a935db276e19b1c7bef0739f2deb7d3aca43c5e26a3c6445351cb2fb8495ea0143db63ee66b0cdff9f69917680151e"
string(32) "4a447a41467058496746505541597033"
string(32) "4a447a41467058496746505541597033"

$ios_token = "78fe0026228470bda1859cbdce28daf5e78323431ff3d7d6199dd5845d8002bb0143db63ee66b0cdff9f69917680151e"; 
$keystring = '00000000000000000000000000000000';
$secret = str_repeat("\0",16); 
$token = "726e527270416e5a5a75535269486575";



$decrypt = sslDecrypt(hex2bin($ios_token), $secret); 
var_dump($decrypt);   

$encrypt = sslEncrypt($token, $secret); 
var_dump($encrypt); // raw
$ios_token_b = bin2hex($encrypt);
var_dump($ios_token_b); // string
$decrypt = sslDecrypt($encrypt, $secret); 
var_dump($decrypt); 
$decrypt = sslDecrypt(hex2bin($ios_token_b), $secret); 
var_dump($decrypt);   


function sslEncrypt($str, $secret) 
{ 
    return openssl_encrypt($str, 'aes-128-ecb', $secret, OPENSSL_RAW_DATA); 
} 

function sslDecrypt($str, $secret) 
{ 
    return openssl_decrypt($str, 'aes-128-ecb', $secret, OPENSSL_RAW_DATA); 
}

funktioniert nur das Entschlüsseln das Verschlüsseln anscheinend aber nicht

Ausgabe ist


string(32) "726e527270416e5a5a75535269486575"
string(48) "xþ

EDIT: Hier gibt es nichts zu sehen :smiley: Erst im nächsten Post :smiley:

Hilft dir das? Kann mich grad schwer rein denken in was du da vor hast…

<? 
$secret = str_repeat("\0",16); 

$ios_token = "78fe0026228470bda1859cbdce28daf5e78323431ff3d7d6199dd5845d8002bb0143db63ee66b0cdff9f69917680151e";  
$token =  "726e527270416e5a5a75535269486575"; 

$decrypt = base64_encode(sslDecrypt(hex2bin($ios_token), $secret)); 
var_dump(base64_decode($decrypt)); 
echo "----------------------------------------------------".PHP_EOL;
$encrypt = sslEncrypt(base64_encode($token), $secret); 
var_dump($encrypt); 

$decrypt = sslDecrypt($encrypt, $secret); 
var_dump($decrypt);
var_dump(base64_decode($decrypt));
echo "----------------------------------------------------".PHP_EOL;
$encrypt = sslEncrypt($decrypt, $secret); 
var_dump($encrypt);
$decrypt = sslDecrypt($encrypt, $secret); 
var_dump($decrypt); 
var_dump(base64_decode($decrypt));
 
 
function sslEncrypt($str, $secret) 
{ 
    return openssl_encrypt($str, 'aes-128-ecb', $secret, OPENSSL_RAW_DATA); 
} 

function sslDecrypt($str, $secret) 
{ 
    return openssl_decrypt($str, 'aes-128-ecb', $secret, OPENSSL_RAW_DATA); 
} 

?>

Ausgabe:

string(32) "726e527270416e5a5a75535269486575"
----------------------------------------------------
string(48) "NɖË`Â(4À)á4eËò4è=–N¸©øŠÓ,Qԕ΍„b*	³•jÛ-"
string(44) "NzI2ZTUyNzI3MDQxNmU1YTVhNzU1MzUyNjk0ODY1NzU="
string(32) "726e527270416e5a5a75535269486575"
----------------------------------------------------
string(48) "NɖË`Â(4À)á4eËò4è=–N¸©øŠÓ,Qԕ΍„b*	³•jÛ-"
string(44) "NzI2ZTUyNzI3MDQxNmU1YTVhNzU1MzUyNjk0ODY1NzU="
string(32) "726e527270416e5a5a75535269486575"

Grüße,
Chris

Fürs erste ist das ok, weil es mir erstmal darum geht den 96 Token zu entschlüsseln und in den 32 Token umzuwandeln.
Eine Kommunikation mit dem 32 Token scheint auch zu gehen, das muss ich mir dann mal näher anschauen. Was halt noch schön wäre, aber nicht zwingend notwendig, wäre den 32 Token wieder zurückrechnen in den 96 Token. Und irgendwie scheint das ja nicht zu klappen (s.o.). Eine Berechnung hin und zurück scheint ja zu funktionieren und der 32 Token ist auch richtig. Nur beim 96 Token kann ich anscheinend nur von diesem der 32 Token berechnen alles was dann zurückgerechnet wird hat ja nur eine Länge von 48 bzw. 44 und entspricht auch nicht dem Ausgangsstring aus dem der 32 Token abgeleitet worden ist.

Kann dir leider nach wie vor nicht folgen :smiley:

Was gibst du rein und was soll rauskommen? Und was willst du danach wieder encrypten oder decrypten?
Oben in meinem letzten Beispiel sollten doch alle Richtungen drin sein?!

Grüße,
Chris

Ja es wird ent- und verschlüsselt.

Ich will eigentlich den Ausgangswert z.B.


16a935db276e19b1c7bef0739f2deb7d3aca43c5e26a3c6445351cb2fb8495ea0143db63ee66b0cdff9f69917680151e

umwandeln in einen Token den ich benutzen kann
also


4a447a41467058496746505541597033

So weit so gut, das funktioniert ja auch dankenswerterweise mit dem Code den Du gepostet hast. Schön wäre es wenn ich vom 32 stelligen Token auch wieder auf den Ausgangswert (96stellig) schließen könnte.
Ich habe also


4a447a41467058496746505541597033

und weis das dies dann


16a935db276e19b1c7bef0739f2deb7d3aca43c5e26a3c6445351cb2fb8495ea0143db63ee66b0cdff9f69917680151e

als 96 stelliger Token verschlüsselt entsprechen würde. Letzter Weg also vom entschlüsselten zum verschlüsselten zurückzuschließen scheint ja aber nicht zu gehen.

Ich kann zwar ver und entschlüsseln


string(32) "4a447a41467058496746505541597033"
string(48) "©5Û'n±ǾðsŸ-ë}:ÊCÅâj<dE5²û„•êCÛcîf°ÍÿŸi‘v€"
string(32) "4a447a41467058496746505541597033"

aber Du wirst mir Recht geben das


©5Û'n±ǾðsŸ-ë}:ÊCÅâj<dE5²û„•êCÛcîf°ÍÿŸi‘v€

nicht


16a935db276e19b1c7bef0739f2deb7d3aca43c5e26a3c6445351cb2fb8495ea0143db63ee66b0cdff9f69917680151e

entspricht. In sofern kann ich nicht Rückschlüsse ziehen wie der 96 String Token eigentlich lauten würde. Ist fürs erste aber egal, es reicht mir erst mal wenn ich von der 96 stelligen verschlüsselten Version die entschlüsselte 32 Stellen Version des Tokens errechnen kann.

was kommt denn raus, wenn man das vermeindlich falsche Ergebnis in HEX konvertiert?

Ansich kommt dann das richtige raus, nur scheint das davon abzuhängen was der ursprüngliche Token ist und das verstehe ich halt nicht. Wenn müsste es ja immer funktionieren.

Bei dem Token


16a935db276e19b1c7bef0739f2deb7d3aca43c5e26a3c6445351cb2fb8495ea0143db63ee66b0cdff9f69917680151e

funktioniert das siehe auch hier

Bei dem Token


78fe0026228470bda1859cbdce28daf5e78323431ff3d7d6199dd5845d8002bb0143db63ee66b0cdff9f69917680151e

geht es aber auf einmal wieder nicht siehe hier, und ich verstehe nicht warum in einem Fall bin2hex funktioniert und im anderen Fall nicht.

Kannst ja mal das Skript aus dem Post 1:1 kopieren und schauen ob es geht. bei mir kommt da wie gesagt nur


string(32) "726e527270416e5a5a75535269486575"
string(48) "xþ

raus.

Geht mit beiden Token:

<?
$secret = str_repeat("\0",16); 

$ios_token1 = "78fe0026228470bda1859cbdce28daf5e78323431ff3d7d6199dd5845d8002bb0143db63ee66b0cdff9f69917680151e";  
$token1 =  "726e527270416e5a5a75535269486575"; 

$ios_token2 = "16a935db276e19b1c7bef0739f2deb7d3aca43c5e26a3c6445351cb2fb8495ea0143db63ee66b0cdff9f69917680151e";
$token2 = "4a447a41467058496746505541597033";



$decrypt = base64_encode(sslDecrypt(hex2bin($ios_token1), $secret)); 
var_dump(base64_decode($decrypt)); 
echo "----------------------------------------------------".PHP_EOL;
$encrypt = sslEncrypt($token1, $secret); 
var_dump(StrToHex($encrypt)); 
$decrypt = sslDecrypt($encrypt, $secret); 
var_dump($decrypt);
$encrypt = sslEncrypt($decrypt, $secret); 
var_dump(StrToHex($encrypt)); 
echo "----------------------------------------------------".PHP_EOL;
echo "----------------------------------------------------".PHP_EOL;
$decrypt = base64_encode(sslDecrypt(hex2bin($ios_token2), $secret)); 
var_dump(base64_decode($decrypt)); 
echo "----------------------------------------------------".PHP_EOL;
$encrypt = sslEncrypt($token2, $secret); 
var_dump(StrToHex($encrypt)); 
$decrypt = sslDecrypt($encrypt, $secret); 
var_dump($decrypt);
$encrypt = sslEncrypt($decrypt, $secret); 
var_dump(StrToHex($encrypt)); 



function sslEncrypt($str, $secret) 
{ 
    return openssl_encrypt($str, 'aes-128-ecb', $secret, OPENSSL_RAW_DATA); 
} 

function sslDecrypt($str, $secret) 
{ 
    return openssl_decrypt($str, 'aes-128-ecb', $secret, OPENSSL_RAW_DATA); 
} 

function StrToHex($string)
{
    $hex='';
    for ($i=0; $i < strlen($string); $i++)
	{
        $hex .= dechex(ord($string[$i]));
    }
    return $hex;
}

function HexToStr($hex)
{
    $string='';
    for ($i=0; $i < strlen($hex)-1; $i+=2)
	{
        $string .= chr(hexdec($hex[$i].$hex[$i+1]));
    }
    return $string;
}
?>

Ausgabe:

string(32) "726e527270416e5a5a75535269486575"
----------------------------------------------------
string(93) "78fe026228470bda1859cbdce28daf5e78323431ff3d7d6199dd5845d802bb143db63ee66b0cdff9f69917680151e"
string(32) "726e527270416e5a5a75535269486575"
string(93) "78fe026228470bda1859cbdce28daf5e78323431ff3d7d6199dd5845d802bb143db63ee66b0cdff9f69917680151e"
----------------------------------------------------
----------------------------------------------------
string(32) "4a447a41467058496746505541597033"
----------------------------------------------------
string(95) "16a935db276e19b1c7bef0739f2deb7d3aca43c5e26a3c6445351cb2fb8495ea143db63ee66b0cdff9f69917680151e"
string(32) "4a447a41467058496746505541597033"
string(95) "16a935db276e19b1c7bef0739f2deb7d3aca43c5e26a3c6445351cb2fb8495ea143db63ee66b0cdff9f69917680151e"

Das Problem sind die Strings die aber eigentlich Hex sind… Dazu noch ein paar Zeichen mit denen die Console nicht klar kommt und deshalb dann die Mischung aus Hex, String, Base64, … :smiley:

Grüße,
Chris

Danke vielmals, wieder was dazugelernt :loveips:

Hex zu String brauchste in dem Beispiel gar nicht, aber hab es mal dazu gemacht, falls du doch noch was damit anstellen magst :slight_smile:

Darf man fragen, was du da wieder schönes baust? :slight_smile:

Grüße,
Chris

Ich habe mich lange geziert, da ich ja nicht bedingungslos Fan von China Zeugs bin, das noch nicht mal eine deutsche Bedienungsanleitung besitzt. Ich habe mir einen Roborock geholt, das Ding hat sich alleine im letzten Jahr über 50 Millionen mal in China verkauft, daher kann das Ding nicht so verkehrt sein und der Preis ist halt unschlagbar. Bei den Verkaufszahlen fängt wahrscheinlich jeder Europäische Produzent das Heulen an, bis 50 Millionen Staubsaugerroboter in Deutschland rumfahren vergehen Jahrzehnte, geschweige denn das es überhaupt so viele Haushalte in Deutschland gibt.

Die Kommunikation funktioniert jetzt schon dank Deiner Hilfe, die Oberfläche sieht so aus und ich hoffe das ich das jetzt dann mal fertig stellen kann.