[Python] naar [PHP] inloggen op een API met een public key

Pagina: 1
Acties:

Vraag


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Tweakers, devs en mede hobbyisten,

Voor mijn domotica systeem (IP-symcon) ben ik een poging aan het doen om mijn Ecovacs stofzuiger te integreren. Ik heb hier een mooi voorbeeld voor gevonden in Python (link). Ik heb wel wat ervaring in Python maar dit is de eerste keer dat ik zo diep ga ;), Maar tot nu toe gaat het redelijk. Het doel is om uit eindelijk een PHP module te bouwen voor IP-symcon. Maar voorlopig zullen het wat losse functies zijn die ik eerst werkend wil hebben. Met PHP heb ik wat meer ervaring maar op het gebeid van encryptie heb ik mij nog nooit aan gewaagd, ook zal de structuur in mijn code en de terminologie misschien niet altijd zo zijn als het hoort. Ook hier is nog veel te leren.

Ik ben hier net een paar weken mee bezig en ik ben in staat om de login URL zo goed als de reproduceren. Maar, helaas zwicht de API nog niet voor mijn programmeer kunsten...

Mijn vraag:
Wat gaat hier nou eindelijk mis? Mijn verdenking ligt bij de RSA encryptie of the base64 de- en encodeing. Maar, heb ik dit wel goed?

Python wpietri/sucks/__init__.py: regel 202:
Python:
202
203
204
205
206
207
208
    def encrypt(text):
        from Crypto.PublicKey import RSA
        from Crypto.Cipher import PKCS1_v1_5
        key = RSA.import_key(b64decode(EcoVacsAPI.PUBLIC_KEY))
        cipher = PKCS1_v1_5.new(key)
        result = cipher.encrypt(bytes(text, 'utf8'))
        return str(b64encode(result), 'utf8')


PHP dixi/IPSEcovacs/firsttests.php: regel 53:
PHP:
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
function encrypt($plaintext) {
    global $key;
    
    //$key = base64_decode($key);
    //$key = bin2hex($key);
    
    $x509 = new File_X509();
    $x509->loadX509($key);
    $pkey = $x509->getPublicKey();
    
    $rsa = new Crypt_RSA();
    $rsa->loadKey($pkey);
    $result = $rsa->encrypt($plaintext);
    //$result = hex2bin($result);
    $result = base64_encode($result);
    return $result;
} // end of function encryptRSA


Gebruikte Library's en Versies:
phpseclib v1.0: http://phpseclib.sourceforge.net/
PHP v5.6
python v3.5.2

Wat ik heb geprobeerd:
- Eerst ben ik begonnen met de public key direct te importeren als als RSA key dit werkte niet... dit bleek via een X509 decryptie wel mogelijk.
- Ik ben wat aan het klooien geweest met de base64 encodeing en decoding (de restantjes staan nog in de functie. Deze gaven niet het gewenste resultaat (vreemd oogende outputs, in iedergeval anders dan de urls die in python krijg)
- Python geeft met de eerste b64decode() een ander resultaat als php dat doet hoewel het de zelfde hexadecimale string (dit is zichtbaar te maken met hex2bin()) is, ziet hij er anders uit:
Python
code:
1
2
3
4
5
from base64 import b64decode, b64encode

PUBLIC_KEY = 'MIIB/TCCAWYCCQDJ7TMYJFzqYDANBgkqhkiG9w0BAQUFADBCMQswCQYDVQQGEwJjbjEVMBMGA1UEBwwMRGVmYXVsdCBDaXR5MRwwGgYDVQQKDBNEZWZhdWx0IENvbXBhbnkgTHRkMCAXDTE3MDUwOTA1MTkxMFoYDzIxMTcwNDE1MDUxOTEwWjBCMQswCQYDVQQGEwJjbjEVMBMGA1UEBwwMRGVmYXVsdCBDaXR5MRwwGgYDVQQKDBNEZWZhdWx0IENvbXBhbnkgTHRkMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDb8V0OYUGP3Fs63E1gJzJh+7iqeymjFUKJUqSD60nhWReZ+Fg3tZvKKqgNcgl7EGXp1yNifJKUNC/SedFG1IJRh5hBeDMGq0m0RQYDpf9l0umqYURpJ5fmfvH/gjfHe3Eg/NTLm7QEa0a0Il2t3Cyu5jcR4zyK6QEPn1hdIGXB5QIDAQABMA0GCSqGSIb3DQEBBQUAA4GBANhIMT0+IyJa9SU8AEyaWZZmT2KEYrjakuadOvlkn3vFdhpvNpnnXiL+cyWy2oU1Q9MAdCTiOPfXmAQt8zIvP2JC8j6yRTcxJCvBwORDyv/uBtXFxBPEC6MDfzU2gKAaHeeJUWrzRv34qFSaYkYta8canK+PSInylQTjJK9VqmjQ'

print(b64decode(PUBLIC_KEY))

>>>>
code:
1
b'0\x82\x01\xfd0\x82\x01f\x02\t\x00\xc9\xed3\x18$\\\xea`0\r\x06\t*\x86H\x86\xf7\r\x01\x01\x05\x05\x000B1\x0b0\t\x06\x03U\x04\x06\x13\x02cn1\x150\x13\x06\x03U\x04\x07\x0c\x0cDefault City1\x1c0\x1a\x06\x03U\x04\n\x0c\x13Default Company Ltd0 \x17\r170509051910Z\x18\x0f21170415051910Z0B1\x0b0\t\x06\x03U\x04\x06\x13\x02cn1\x150\x13\x06\x03U\x04\x07\x0c\x0cDefault City1\x1c0\x1a\x06\x03U\x04\n\x0c\x13Default Company Ltd0\x81\x9f0\r\x06\t*\x86H\x86\xf7\r\x01\x01\x01\x05\x00\x03\x81\x8d\x000\x81\x89\x02\x81\x81\x00\xdb\xf1]\x0eaA\x8f\xdc[:\xdcM`\'2a\xfb\xb8\xaa{)\xa3\x15B\x89R\xa4\x83\xebI\xe1Y\x17\x99\xf8X7\xb5\x9b\xca*\xa8\rr\t{\x10e\xe9\xd7#b|\x92\x944/\xd2y\xd1F\xd4\x82Q\x87\x98Ax3\x06\xabI\xb4E\x06\x03\xa5\xffe\xd2\xe9\xaaaDi\'\x97\xe6~\xf1\xff\x827\xc7{q \xfc\xd4\xcb\x9b\xb4\x04kF\xb4"]\xad\xdc,\xae\xe67\x11\xe3<\x8a\xe9\x01\x0f\x9fX] e\xc1\xe5\x02\x03\x01\x00\x010\r\x06\t*\x86H\x86\xf7\r\x01\x01\x05\x05\x00\x03\x81\x81\x00\xd8H1=>#"Z\xf5%<\x00L\x9aY\x96fOb\x84b\xb8\xda\x92\xe6\x9d:\xf9d\x9f{\xc5v\x1ao6\x99\xe7^"\xfes%\xb2\xda\x855C\xd3\x00t$\xe28\xf7\xd7\x98\x04-\xf32/?bB\xf2>\xb2E71$+\xc1\xc0\xe4C\xca\xff\xee\x06\xd5\xc5\xc4\x13\xc4\x0b\xa3\x03\x7f56\x80\xa0\x1a\x1d\xe7\x89Qj\xf3F\xfd\xf8\xa8T\x9abF-k\xc7\x1a\x9c\xaf\x8fH\x89\xf2\x95\x04\xe3$\xafU\xaah\xd0'

PHP:
PHP:
1
2
3
4
5
$PUBLIC_KEY = 'MIIB/TCCAWYCCQDJ7TMYJFzqYDANBgkqhkiG9w0BAQUFADBCMQswCQYDVQQGEwJjbjEVMBMGA1UEBwwMRGVmYXVsdCBDaXR5MRwwGgYDVQQKDBNEZWZhdWx0IENvbXBhbnkgTHRkMCAXDTE3MDUwOTA1$

$echo = base64_decode($PUBLIC_KEY);

echo bin2hex($echo);

>>>>
code:
1
308201fd30820166020900c9ed3318245cea60300d06092a864886f70d01010505003042310b300906035504061302636e3115301306035504070c0c44656661756c742043697479311c301a060355040a0c1344656661756c7420436f6d70616e79204c74643020170d3137303530393035313931305a180f32313137303431353035313931305a3042310b300906035504061302636e3115301306035504070c0c44656661756c742043697479311c301a060355040a0c1344656661756c7420436f6d70616e79204c746430819f300d06092a864886f70d010101050003818d0030818902818100dbf15d0e61418fdc5b3adc4d60273261fbb8aa7b29a315428952a483eb49e1591799f85837b59bca2aa80d72097b1065e9d723627c9294342fd279d146d48251879841783306ab49b4450603a5ff65d2e9aa6144692797e67ef1ff8237c77b7120fcd4cb9bb4046b46b4225daddc2caee63711e33c8ae9010f9f585d2065c1e50203010001300d06092a864886f70d010105050003818100d848313d3e23225af5253c004c9a5996664f628462b8da92e69d3af9649f7bc5761a6f3699e75e22fe7325b2da853543d3007424e238f7d798042df3322f3f6242f23eb2453731242bc1c0e443caffee06d5c5c413c40ba3037f353680a01a1de789516af346fdf8a8549a62462d6bc71a9caf8f4889f29504e324af55aa68d0

Heeft dit gevolgen, ik weet het niet....

Met mijn PHP script dat ik nu in elkaar geknutseld heb [linkje]
ben ik in staat om zo goed als gelijke URL te genereren om in te loggen op de API
Hierbij heb ik van class "EcoVacsAPI" de functies __init__(), __sign(), __call_main_api(), md5() en encrypt() door gespit.
code:
1
2
Python output: https://eco-nl-api.ecovacs.com/v1/private/nl/en/d252b60aae03e4123236560e644a2868/i_eco_e/1.3.5/c_googleplay/1/user/login?account=cW5ilB%2Fp59GQvP0BBQtri0GxAg9X3dphBYPeQwaG7CLbZ9hr7pj%2Bb%2B90F2UGeol%2Bb3g12M0e3fFvgXMmsKbmzre3lpU9RkfPzy71Nh6dMkr9Sd0GmWfMXOUWZPsuSZXoTbKS%2BGgNbmxXEmovHjHP36lCkQ5zRPC%2BX6ncZV3ijNI%3D&password=YFC50Ooo%2FIRFUzKxyuchtitM%2FGyWXtBUosoka%2Bs1rvFqTTYTtRunjrwD9uCPJKOhxclA2b4ojn7AqfNaGchjVMTwqcLZOK7sCzGkSzQ605Oi3%2FMhc5Eb9OcwFiPMnuE5x610AzeTBhtDiOuxP1FcRRndozG4XtQE6tYv9QtGa0k%3D&requestId=35d39fec6bb359e4cab2225ca3185d8d&authTimespan=1533632529513&authTimeZone=GMT-8&authAppkey=eJUWrzRv34qFSaYk&authSign=5bd06f0de6ae4a2945381281954ea324
PHP output:    https://eco-nl-api.ecovacs.com/v1/private/nl/en/baf5351984bb840fc0007a9a66cba479/i_eco_e/1.3.5/c_googleplay/1/user/login?account=UZP0m7NrlrScwed2SwiSRVl2VVRn3TXcAmHvNZk8mS%2FYhmX3qGI1GZZfkfC4zrXx%2FGtGs%2Fs80HNQ%2ByY3zk1TZAS3q%2BStP8k5PY43SKvIffhNmBBv3SAw47zRSnoJxdHIndzoDB1gjFbnyCscE4Ui2GtsCVdbA8l9TsT2UwvuiZY%3D&password=14itA%2BXJks75hPc12JKFERx2KY9tzMSi%2FfmQoTnvtN%2BW%2BZyfYGAVVAmv7GV4M%2B7TaM5o1iDAJHA1yVdHpGXtOVVpEiDhVZlA2yoi1Xpdksd0AJWFdpMWY%2BWTPfUx524iWphClXDHehXdlxEHkcQ2NU%2BJ7%2BUiWjP4Gu%2Fi2cXsIp8%3D&requestId=baf5351984bb840fc0007a9a66cba479&authTimespan=1533559897000&authTimeZone=GMT-8&authAppkey=eJUWrzRv34qFSaYk&authSign=5e7a0a735ae4d5d29c282b820d62e729


Edit:
Deze had ik nog willen toevoegen:
De response van de API, de python geeft een password error maar als ik de gegevens wel goed invul krijg ik netjes een key teurg voor de xmpp communicatie (de volgende stap):
Python: {'msg': '当前密码错误', 'data': None, 'time': 1533632529879, 'code': '1005'}
PHP {"code":"0002","msg":"接口鉴权失败","time":1533627991827}

Met vriendelijke groet,
Martijn

[ Voor 7% gewijzigd door Verwijderd op 07-08-2018 12:07 ]

Beste antwoord (via Verwijderd op 12-08-2018 22:40)


  • Vaan Banaan
  • Registratie: Februari 2001
  • Niet online

Vaan Banaan

Heeft ook Apache ontdekt

Ok, er missen dus juist een aantal items.
• De deviceID is toch de hele md5
• Ik zie bij de authTimespan:int(time.time() * 1000), dit is iets met milliseconden en jij doet de tijd in seconden * 1000, Kan een issue zijn als timing op de server heel strak staat.
• Alle key/value pairs van meta en login gebruiken (behalve authAppkey, die komt in de authSign als eerste met alleen de waarde, je hebt hem wel nodig om de URL te bakken)
• Key-names op alfabet sorteren

Je hebt overigens al een voorbeeld met de juiste uitkomst, namelijk de eerste URL in Python:
code:
1
2
3
4
5
6
7
8
9
10
https://eco-nl-api.ecovacs.com/v1/private/nl/en
/d252b60aae03e4123236560e644a2868 <-- deviceId
/i_eco_e/1.3.5/c_googleplay/1/user/login
? account=cW5ilB%2Fp59GQvP0BBQtri0GxAg9X3dphBYPeQwaG7CLbZ9hr7pj%2Bb%2B90F2UGeol%2Bb3g12M0e3fFvgXMmsKbmzre3lpU9RkfPzy71Nh6dMkr9Sd0GmWfMXOUWZPsuSZXoTbKS%2BGgNbmxXEmovHjHP36lCkQ5zRPC%2BX6ncZV3ijNI%3D
& password=YFC50Ooo%2FIRFUzKxyuchtitM%2FGyWXtBUosoka%2Bs1rvFqTTYTtRunjrwD9uCPJKOhxclA2b4ojn7AqfNaGchjVMTwqcLZOK7sCzGkSzQ605Oi3%2FMhc5Eb9OcwFiPMnuE5x610AzeTBhtDiOuxP1FcRRndozG4XtQE6tYv9QtGa0k%3D
& requestId=35d39fec6bb359e4cab2225ca3185d8d
& authTimespan=1533632529513
& authTimeZone=GMT-8
& authAppkey=eJUWrzRv34qFSaYk
& authSign=5bd06f0de6ae4a2945381281954ea324 <-- Dit is je controle

LET OP: account en password zijn oorspronkeljik base64, die moet je voor deze controle nog wel URL decoden (%2B = '+', %2F = '/' en %3D = '=')
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
eJUWrzRv34qFSaYk <-- authAppkey
account=cW5ilB/p59GQvP0BBQtri0GxAg9X3dphBYPeQwaG7CLbZ9hr7pj+b+90F2UGeol+b3g12M0e3fFvgXMmsKbmzre3lpU9RkfPzy71Nh6dMkr9Sd0GmWfMXOUWZPsuSZXoTbKS+GgNbmxXEmovHjHP36lCkQ5zRPC+X6ncZV3ijNI=
appCode=i_eco_e
appVersion=1.3.5
authTimeZone=GMT-8
authTimespan=1533632529513
channel=c_googleplay
country=nl
deviceId=d252b60aae03e4123236560e644a2868
deviceType=1
lang=en
password=YFC50Ooo/IRFUzKxyuchtitM/GyWXtBUosoka+s1rvFqTTYTtRunjrwD9uCPJKOhxclA2b4ojn7AqfNaGchjVMTwqcLZOK7sCzGkSzQ605Oi3/Mhc5Eb9OcwFiPMnuE5x610AzeTBhtDiOuxP1FcRRndozG4XtQE6tYv9QtGa0k=
requestId=35d39fec6bb359e4cab2225ca3185d8d
Cyu5jcR4zyK6QEPn1hdIGXB5QIDAQABMA0GC <-- secret
of in 1 regel
code:
1
eJUWrzRv34qFSaYkaccount=cW5ilB/p59GQvP0BBQtri0GxAg9X3dphBYPeQwaG7CLbZ9hr7pj+b+90F2UGeol+b3g12M0e3fFvgXMmsKbmzre3lpU9RkfPzy71Nh6dMkr9Sd0GmWfMXOUWZPsuSZXoTbKS+GgNbmxXEmovHjHP36lCkQ5zRPC+X6ncZV3ijNI=appCode=i_eco_eappVersion=1.3.5authTimeZone=GMT-8authTimespan=1533632529513channel=c_googleplaycountry=nldeviceId=d252b60aae03e4123236560e644a2868deviceType=1lang=enpassword=YFC50Ooo/IRFUzKxyuchtitM/GyWXtBUosoka+s1rvFqTTYTtRunjrwD9uCPJKOhxclA2b4ojn7AqfNaGchjVMTwqcLZOK7sCzGkSzQ605Oi3/Mhc5Eb9OcwFiPMnuE5x610AzeTBhtDiOuxP1FcRRndozG4XtQE6tYv9QtGa0k=requestId=35d39fec6bb359e4cab2225ca3185d8dCyu5jcR4zyK6QEPn1hdIGXB5QIDAQABMA0GC
spoiler: md5
5bd06f0de6ae4a2945381281954ea324 *O*

Verder zal je nog wel wat moeten herschrijven, want de 2de URL bouwt zo te zien met net andere gegevens de authSign op.
(Geen account en password, ik neem aan dat het wel dezelfde deviceId MOET blijven en nieuw zijn de gegevens.uit de login info response van de eerste URL)
code:
1
2
3
4
5
6
7
8
9
10
login_info = self.__call_main_api('user/login',
                                          ('account', self.encrypt(account_id)),
                                          ('password', self.encrypt(password_hash)))
        self.uid = login_info['uid']
        self.login_access_token = login_info['accessToken']
        self.auth_code = self.__call_main_api('user/getAuthCode',
                                              ('uid', self.uid),
                                              ('accessToken', self.login_access_token))['authCode']
        self.user_access_token = self.__call_login_by_it_token()['token']
        _LOGGER.debug("EcoVacsAPI connection complete")

[ Voor 12% gewijzigd door Vaan Banaan op 10-08-2018 18:10 ]

500 "The server made a boo boo"

Alle reacties


Acties:
  • +1 Henk 'm!

  • Vaan Banaan
  • Registratie: Februari 2001
  • Niet online

Vaan Banaan

Heeft ook Apache ontdekt

Pas op met de inlog URL's, daar staan (hoewel versleuteld) je inloggegevens in...

Wat beteft de inlogpogingen: krijg je bij geen van beide een access token?
Python: 接口鉴权参数缺失 Missing interface authentication parameters
Of heb je hier niet je echte gebruikersnaam en wachtwoord gebruikt? (code 1005)
code:
1
2
3
4
5
6
7
8
9
        if json['code'] == '0000':
            return json['data']
        elif json['code'] == '1005':
            _LOGGER.warning("incorrect email or password")
            raise ValueError("incorrect email or password")
        else:
            _LOGGER.error("call to {} failed with {}".format(function, json))
            raise RuntimeError("failure code {} ({}) for call {} and parameters {}".format(
                json['code'], json['msg'], function, args))

PHP: 接口鉴权失败: Interface authentication failed
Deze doet het dus ook niet, maar had je al verwacht. Deze code krijg ik overigens inmiddels ook als ik nu de eerste URL probeer (waarschijnlijk vanwege de timestamps)

Die public keys strings zijn overigens wel hetzelfde
b'0 \x82 \x01 \xfd 0.... is gelijk aan
'0' 0x82 0x01 0xfd '0' ...is gelijk aan
30 82 01 fd 30...

Ik heb niog gezocht naar het device ID, dat lijkt inderdaad de Unix Epoch te zijn.
Python (cli.py): device_id = EcoVacsAPI.md5(str(time.time()))
PHP: md5(time())
En dan moet je daar zo te zien de eerste 8 bytes van nemen. self.resource = device_id[0:8]

Ik programmeer niet in PHP of Python, maar zo te zien is je authSign waarde niet gped.
Je moet dus vooral gaan experimenteren zodat je zeker weet dat je uitkomst via def __sign(self, params):
code:
1
2
3
sign_on_text = EcoVacsAPI.CLIENT_KEY + ''.join(
            [k + '=' + str(sign_on~[k]) for k in sorted(sign_on.keys())]) + EcoVacsAPI.SECRET[
result['authSign'] = self.md5(sign_on_text)
ook met je eigen bouwsel overeen komt
code:
1
2
3
4
5
6
7
8
    foreach($metas as $key => $value) {
        $string = $string.$key.'='.$value;
    }
    return $ckey.$string.$secret;

$authSign = sign($meta);

$login['authSign']  = md5($authSign);

De md5 stap kan je dus ook weglaten met debuggen, dan zouden de strings van sign_on_text en $authSign gelijk moeten zijn.

Misschien staat een sortering niet goed? En het lijkt alsof je er ook de encryted account en password bij plakt. Ik vraag me af of dat nodig is. Maar goed, dat moet je zelf wel uit kunnen vinden.

Als je zeker wilt weten of je account en password encrypt goed gaan, kun je dat testen door zelf een keypair aan te maken en die public te gebruiken. Dan kun je voor beide er een decrypt met private key op loslaten om te controleren dat het juist is.
Overigens is dit wel een heel vaag certificaat. Zo te zien alleen nodig als container voor de public key.

[ Voor 10% gewijzigd door Vaan Banaan op 09-08-2018 20:20 ]

500 "The server made a boo boo"


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Bedankt voor het nemen van de moeite om mijn probleem te bekijken en te antwoorden!

De links die ik geplaatst heb zijn links die gegenereerd zijn met een foute gebruikers naam en wachtwoord. Dit heb ik inderdaad bewust gedaan om de reden die jij meer dan terecht aanhaalt! De antwoorden van de api kloppen dus in dat opzicht. Van de Python URL krijg ik een ander antwoord:
{"code":"1005","msg":"当前密码错误","time":1533902592399,"data":null}
当前密码错误: Huidige wachtwoordfout

De device_id[0:8] heb ik overheen gekeken dit heb ik nu aangepast naar substr(md5(time()), 0, 8);

Mijn grootste probleem zit hem in de __sign() functie inderdaad... Hier zitten grote verschillen in met de output die ik nu in de sucks gegenereerd heb.
code:
1
2
Python:  eJUWrzRv34qFSaYkaccount=fjPqxztluo6UhPHwo87OVynFNly0eHc+f4VC6QGcWelo9kS+MN1m4/13XckxEuuPzGoI5MYiubIaWhnsRbpzHqGUD0/YkVP/4WT2jhsBXZ4tlMxX+lMKE25YncaQHRSs80aWk0sPNNKAZm5l/EWyI5Z3F1i0L9yNZYZ3rsXdTjA=appCode=i_eco_eappVersion=1.3.5authTimeZone=GMT-8authTimespan=1533903118436channel=c_googleplaycountry=nldeviceId=c670e6fc9d4753af09788e7aaa9502dedeviceType=1lang=enpassword=tOSANVu3cq1JXdEHr/JqjRGoj03X1Sm9o/iM/pxZkBMqSSgXa45Sqcs+UEmjJOEHJmLmbcxxeoUaFaiiSYZnQc/Yss0yegbXuO9pzoFBEZPmaPcxcdjAfX8okDeuhZcqzGpL3C2pftH3P8lUTGiQaBCPTIYePx+p3+LTPn3MTpU=requestId=035ab98309f011dca9affc7aecad68edCyu5jcR4zyK6QEPn1hdIGXB5QIDAQABMA0GC
PHP:    eJUWrzRv34qFSaYkappCode=i_eco_eappVersion=1.3.5channel=c_googleplaycountry=nldeviceId=7375ebf8deviceType=1lang=enCyu5jcR4zyK6QEPn1hdIGXB5QIDAQABMA0GC

Alleen aan de lengte kun je al snel zien dat daar geen *piep* klopt |:( Ik meende dat ik deze wel gecontroleerd had, maar goed blijkbaar niet goed genoeg.

Hier ga ik mee aan het werk. Ik laat het nog even weten.

Groeten Martijn

[ Voor 0% gewijzigd door Verwijderd op 10-08-2018 16:55 . Reden: [mono] tags ipv [cmd] ]


Acties:
  • +1 Henk 'm!

  • DJMaze
  • Registratie: Juni 2002
  • Niet online
Verwijderd schreef op vrijdag 10 augustus 2018 @ 14:15:
Alleen aan de lengte kun je al snel zien dat daar geen *piep* klopt |:( Ik meende dat ik deze wel gecontroleerd had, maar goed blijkbaar niet goed genoeg.
Als je de data uitlijnt zie je direct wat er mist
code:
1
2
Python: eJUWrzRv34qFSaYkaccount=fjPqxztluo6UhPHwo87OVynFNly0eHc+f4VC6QGcWelo9kS+MN1m4/13XckxEuuPzGoI5MYiubIaWhnsRbpzHqGUD0/YkVP/4WT2jhsBXZ4tlMxX+lMKE25YncaQHRSs80aWk0sPNNKAZm5l/EWyI5Z3F1i0L9yNZYZ3rsXdTjA=appCode=i_eco_eappVersion=1.3.5authTimeZone=GMT-8authTimespan=1533903118436channel=c_googleplaycountry=nldeviceId=c670e6fc9d4753af09788e7aaa9502dedeviceType=1lang=enpassword=tOSANVu3cq1JXdEHr/JqjRGoj03X1Sm9o/iM/pxZkBMqSSgXa45Sqcs+UEmjJOEHJmLmbcxxeoUaFaiiSYZnQc/Yss0yegbXuO9pzoFBEZPmaPcxcdjAfX8okDeuhZcqzGpL3C2pftH3P8lUTGiQaBCPTIYePx+p3+LTPn3MTpU=requestId=035ab98309f011dca9affc7aecad68edCyu5jcR4zyK6QEPn1hdIGXB5QIDAQABMA0GC
PHP:    eJUWrzRv34qFSaYk                                                                                                                                                                                    appCode=i_eco_eappVersion=1.3.5                                            channel=c_googleplaycountry=nldeviceId=7375ebf8                        deviceType=1lang=en                                                                                                                                                                                                                               Cyu5jcR4zyK6QEPn1hdIGXB5QIDAQABMA0GC

Maak je niet druk, dat doet de compressor maar


Acties:
  • Beste antwoord
  • +1 Henk 'm!

  • Vaan Banaan
  • Registratie: Februari 2001
  • Niet online

Vaan Banaan

Heeft ook Apache ontdekt

Ok, er missen dus juist een aantal items.
• De deviceID is toch de hele md5
• Ik zie bij de authTimespan:int(time.time() * 1000), dit is iets met milliseconden en jij doet de tijd in seconden * 1000, Kan een issue zijn als timing op de server heel strak staat.
• Alle key/value pairs van meta en login gebruiken (behalve authAppkey, die komt in de authSign als eerste met alleen de waarde, je hebt hem wel nodig om de URL te bakken)
• Key-names op alfabet sorteren

Je hebt overigens al een voorbeeld met de juiste uitkomst, namelijk de eerste URL in Python:
code:
1
2
3
4
5
6
7
8
9
10
https://eco-nl-api.ecovacs.com/v1/private/nl/en
/d252b60aae03e4123236560e644a2868 <-- deviceId
/i_eco_e/1.3.5/c_googleplay/1/user/login
? account=cW5ilB%2Fp59GQvP0BBQtri0GxAg9X3dphBYPeQwaG7CLbZ9hr7pj%2Bb%2B90F2UGeol%2Bb3g12M0e3fFvgXMmsKbmzre3lpU9RkfPzy71Nh6dMkr9Sd0GmWfMXOUWZPsuSZXoTbKS%2BGgNbmxXEmovHjHP36lCkQ5zRPC%2BX6ncZV3ijNI%3D
& password=YFC50Ooo%2FIRFUzKxyuchtitM%2FGyWXtBUosoka%2Bs1rvFqTTYTtRunjrwD9uCPJKOhxclA2b4ojn7AqfNaGchjVMTwqcLZOK7sCzGkSzQ605Oi3%2FMhc5Eb9OcwFiPMnuE5x610AzeTBhtDiOuxP1FcRRndozG4XtQE6tYv9QtGa0k%3D
& requestId=35d39fec6bb359e4cab2225ca3185d8d
& authTimespan=1533632529513
& authTimeZone=GMT-8
& authAppkey=eJUWrzRv34qFSaYk
& authSign=5bd06f0de6ae4a2945381281954ea324 <-- Dit is je controle

LET OP: account en password zijn oorspronkeljik base64, die moet je voor deze controle nog wel URL decoden (%2B = '+', %2F = '/' en %3D = '=')
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
eJUWrzRv34qFSaYk <-- authAppkey
account=cW5ilB/p59GQvP0BBQtri0GxAg9X3dphBYPeQwaG7CLbZ9hr7pj+b+90F2UGeol+b3g12M0e3fFvgXMmsKbmzre3lpU9RkfPzy71Nh6dMkr9Sd0GmWfMXOUWZPsuSZXoTbKS+GgNbmxXEmovHjHP36lCkQ5zRPC+X6ncZV3ijNI=
appCode=i_eco_e
appVersion=1.3.5
authTimeZone=GMT-8
authTimespan=1533632529513
channel=c_googleplay
country=nl
deviceId=d252b60aae03e4123236560e644a2868
deviceType=1
lang=en
password=YFC50Ooo/IRFUzKxyuchtitM/GyWXtBUosoka+s1rvFqTTYTtRunjrwD9uCPJKOhxclA2b4ojn7AqfNaGchjVMTwqcLZOK7sCzGkSzQ605Oi3/Mhc5Eb9OcwFiPMnuE5x610AzeTBhtDiOuxP1FcRRndozG4XtQE6tYv9QtGa0k=
requestId=35d39fec6bb359e4cab2225ca3185d8d
Cyu5jcR4zyK6QEPn1hdIGXB5QIDAQABMA0GC <-- secret
of in 1 regel
code:
1
eJUWrzRv34qFSaYkaccount=cW5ilB/p59GQvP0BBQtri0GxAg9X3dphBYPeQwaG7CLbZ9hr7pj+b+90F2UGeol+b3g12M0e3fFvgXMmsKbmzre3lpU9RkfPzy71Nh6dMkr9Sd0GmWfMXOUWZPsuSZXoTbKS+GgNbmxXEmovHjHP36lCkQ5zRPC+X6ncZV3ijNI=appCode=i_eco_eappVersion=1.3.5authTimeZone=GMT-8authTimespan=1533632529513channel=c_googleplaycountry=nldeviceId=d252b60aae03e4123236560e644a2868deviceType=1lang=enpassword=YFC50Ooo/IRFUzKxyuchtitM/GyWXtBUosoka+s1rvFqTTYTtRunjrwD9uCPJKOhxclA2b4ojn7AqfNaGchjVMTwqcLZOK7sCzGkSzQ605Oi3/Mhc5Eb9OcwFiPMnuE5x610AzeTBhtDiOuxP1FcRRndozG4XtQE6tYv9QtGa0k=requestId=35d39fec6bb359e4cab2225ca3185d8dCyu5jcR4zyK6QEPn1hdIGXB5QIDAQABMA0GC
spoiler: md5
5bd06f0de6ae4a2945381281954ea324 *O*

Verder zal je nog wel wat moeten herschrijven, want de 2de URL bouwt zo te zien met net andere gegevens de authSign op.
(Geen account en password, ik neem aan dat het wel dezelfde deviceId MOET blijven en nieuw zijn de gegevens.uit de login info response van de eerste URL)
code:
1
2
3
4
5
6
7
8
9
10
login_info = self.__call_main_api('user/login',
                                          ('account', self.encrypt(account_id)),
                                          ('password', self.encrypt(password_hash)))
        self.uid = login_info['uid']
        self.login_access_token = login_info['accessToken']
        self.auth_code = self.__call_main_api('user/getAuthCode',
                                              ('uid', self.uid),
                                              ('accessToken', self.login_access_token))['authCode']
        self.user_access_token = self.__call_login_by_it_token()['token']
        _LOGGER.debug("EcoVacsAPI connection complete")

[ Voor 12% gewijzigd door Vaan Banaan op 10-08-2018 18:10 ]

500 "The server made a boo boo"


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Ik heb de data uit de jouw voorgestelde controle even op een hoop gegooid een beetje gehusseld en opnieuw door mijn sign() functie gedraaid.
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
<?

$authAppkey         = 'eJUWrzRv34qFSaYk';
$t['country']       = 'nl';
$t['deviceId']      = 'd252b60aae03e4123236560e644a2868';
$t['deviceType']    = '1';
$t['lang']          = 'en';
$t['password']      = 'YFC50Ooo/IRFUzKxyuchtitM/GyWXtBUosoka+s1rvFqTTYTtRunjrwD9uCPJKOhxclA2b4ojn7AqfNaGchjVMTwqcLZOK7sCzGkSzQ605Oi3/Mhc5Eb9OcwFiPMnuE5x610AzeTBhtDiOuxP1FcRRndozG4XtQE6tYv9QtGa0k=';
$t['requestId']     = '35d39fec6bb359e4cab2225ca3185d8d';
$t['account']       = 'cW5ilB/p59GQvP0BBQtri0GxAg9X3dphBYPeQwaG7CLbZ9hr7pj+b+90F2UGeol+b3g12M0e3fFvgXMmsKbmzre3lpU9RkfPzy71Nh6dMkr9Sd0GmWfMXOUWZPsuSZXoTbKS+GgNbmxXEmovHjHP36lCkQ5zRPC+X6ncZV3ijNI=';
$t['appCode']       = 'i_eco_e';
$t['appVersion']    = '1.3.5';
$t['authTimeZone']  = 'GMT-8';
$t['authTimespan']  = '1533632529513';
$t['channel']       = 'c_googleplay';
$secret             = 'Cyu5jcR4zyK6QEPn1hdIGXB5QIDAQABMA0GC';

function sign($metas) {
    global $authAppkey, $secret;

    ksort($metas);
    
    $string = '';
    
    foreach($metas as $key => $value) {
        $string = $string.$key.'='.$value;
    }
    return $authAppkey.$string.$secret;
}

echo sign($t);
echo '
';
echo md5(sign($t));

?>

output:
eJUWrzRv34qFSaYkaccount=cW5ilB/p59GQvP0BBQtri0GxAg9X3dphBYPeQwaG7CLbZ9hr7pj+b+90F2UGeol+b3g12M0e3fFvgXMmsKbmzre3lpU9RkfPzy71Nh6dMkr9Sd0GmWfMXOUWZPsuSZXoTbKS+GgNbmxXEmovHjHP36lCkQ5zRPC+X6ncZV3ijNI=appCode=i_eco_eappVersion=1.3.5authTimeZone=GMT-8authTimespan=1533632529513channel=c_googleplaycountry=nldeviceId=d252b60aae03e4123236560e644a2868deviceType=1lang=enpassword=YFC50Ooo/IRFUzKxyuchtitM/GyWXtBUosoka+s1rvFqTTYTtRunjrwD9uCPJKOhxclA2b4ojn7AqfNaGchjVMTwqcLZOK7sCzGkSzQ605Oi3/Mhc5Eb9OcwFiPMnuE5x610AzeTBhtDiOuxP1FcRRndozG4XtQE6tYv9QtGa0k=requestId=35d39fec6bb359e4cab2225ca3185d8dCyu5jcR4zyK6QEPn1hdIGXB5QIDAQABMA0GC

5bd06f0de6ae4a2945381281954ea324

vergeleken met de md5 uitkomst van de python:
5bd06f0de6ae4a2945381281954ea324
Dit gaat dus goed.

Terug naar mijn hoofd script... en nou oppassen dat het geen rommeltje wordt }:O

Allereerst de DeviceID, in een oude java code, die ook geschreven is voor deze stofzuigers, heb ik gevonden dat dit gewoon een random getal mag zijn ik heb besloten hier nu een vast nummer voor te nemen en deze met md5 om te gooien zo dat hier een statisch element ontstaat, wat makkelijker is voor het vergelijken.

De time() * 1000 is een goeie inderdaad ik heb het als volgt aan gepast:
$meta['authTimespan'] = round(microtime(true)*1000);

Nu de uitvoering:
ondertussen ben ik op de achtergrond een beetje mijn eventuele module aan het inrichten vandaar dat mijn Github een beetje veranderd is. Ik heb daar een test mapje aan gemaakt waar mijn tests in komen.
dixi83/IPSEcovacs/tests/testsRSA.php

Helaas, nog geen 0000 response van de API. Wel heb ik nu de authSign juist gegenereerd.

Dit is mijn output nu van de bovenstaande file:
code:
1
2
3
4
5
6
Python: eJUWrzRv34qFSaYkaccount=cW5ilB/p59GQvP0BBQtri0GxAg9X3dphBYPeQwaG7CLbZ9hr7pj+b+90F2UGeol+b3g12M0e3fFvgXMmsKbmzre3lpU9RkfPzy71Nh6dMkr9Sd0GmWfMXOUWZPsuSZXoTbKS+GgNbmxXEmovHjHP36lCkQ5zRPC+X6ncZV3ijNI=appCode=i_eco_eappVersion=1.3.5authTimeZone=GMT-8authTimespan=1533632529513channel=c_googleplaycountry=nldeviceId=d252b60aae03e4123236560e644a2868deviceType=1lang=enpassword=YFC50Ooo/IRFUzKxyuchtitM/GyWXtBUosoka+s1rvFqTTYTtRunjrwD9uCPJKOhxclA2b4ojn7AqfNaGchjVMTwqcLZOK7sCzGkSzQ605Oi3/Mhc5Eb9OcwFiPMnuE5x610AzeTBhtDiOuxP1FcRRndozG4XtQE6tYv9QtGa0k=requestId=35d39fec6bb359e4cab2225ca3185d8dCyu5jcR4zyK6QEPn1hdIGXB5QIDAQABMA0GC
PHP:    eJUWrzRv34qFSaYkaccount=m7yYDe/G+CnH5Vw3zwFA/J9MnshHlO8vvd1Y1lsQ39R1okFgpC9JIxlyQw1Cgv08fOug5F6TWcVjAexmYm5M3WdaKUN2xVpW/cb2wQkedyzlu8HwXzprgLwfFpHrHVHWOEWsubO/eL4i4WDLiN2P44Js4Zm+BwDpywl1tQc7p/Y=appCode=i_eco_eappVersion=1.3.5authTimeZone=GMT-8authTimespan=1533931031234channel=c_googleplaycountry=nldeviceId=5888c333257abc2c6fbb7bed22b09dc5deviceType=1lang=enpassword=C+1DydYuXbaE3SQyxCaui8rLYLnMlbsDO3cUS9kPpn14ly9fxKPhftCZ0mdUJ+ptAR4cOdfQKynARD1oS+HM9yC1yb0Hwg6BTFP220fh2uVBJe6ruAObdOwi10nmDSj9Tyh1NLEenrZ/RBhJzU/ke80NB1TkhuDqtl+YI0OyPzc=requestId=5888c333257abc2c6fbb7bed22b09dc5Cyu5jcR4zyK6QEPn1hdIGXB5QIDAQABMA0GC
Python: https://eco-nl-api.ecovacs.com/v1/private/nl/en/c670e6fc9d4753af09788e7aaa9502de/i_eco_e/1.3.5/c_googleplay/1/user/login?account=fjPqxztluo6UhPHwo87OVynFNly0eHc+f4VC6QGcWelo9kS+MN1m4/13XckxEuuPzGoI5MYiubIaWhnsRbpzHqGUD0/YkVP/4WT2jhsBXZ4tlMxX+lMKE25YncaQHRSs80aWk0sPNNKAZm5l/EWyI5Z3F1i0L9yNZYZ3rsXdTjA=&password=tOSANVu3cq1JXdEHr/JqjRGoj03X1Sm9o/iM/pxZkBMqSSgXa45Sqcs+UEmjJOEHJmLmbcxxeoUaFaiiSYZnQc/Yss0yegbXuO9pzoFBEZPmaPcxcdjAfX8okDeuhZcqzGpL3C2pftH3P8lUTGiQaBCPTIYePx+p3+LTPn3MTpU=&requestId=035ab98309f011dca9affc7aecad68ed&authTimespan=1533903118436&authTimeZone=GMT-8&authAppkey=eJUWrzRv34qFSaYk&authSign=7455460a324a0d2bf159c2f16c10f698
PHP:    https://eco-nl-api.ecovacs.com/v1/private/nl/en/5888c333257abc2c6fbb7bed22b09dc5/i_eco_e/1.3.5/c_googleplay/1/user/login?account=m7yYDe/G+CnH5Vw3zwFA/J9MnshHlO8vvd1Y1lsQ39R1okFgpC9JIxlyQw1Cgv08fOug5F6TWcVjAexmYm5M3WdaKUN2xVpW/cb2wQkedyzlu8HwXzprgLwfFpHrHVHWOEWsubO/eL4i4WDLiN2P44Js4Zm+BwDpywl1tQc7p/Y=&password=C+1DydYuXbaE3SQyxCaui8rLYLnMlbsDO3cUS9kPpn14ly9fxKPhftCZ0mdUJ+ptAR4cOdfQKynARD1oS+HM9yC1yb0Hwg6BTFP220fh2uVBJe6ruAObdOwi10nmDSj9Tyh1NLEenrZ/RBhJzU/ke80NB1TkhuDqtl+YI0OyPzc=&requestId=5888c333257abc2c6fbb7bed22b09dc5&authTimespan=1533931031234&authTimeZone=GMT-8&authAppkey=eJUWrzRv34qFSaYk&authSign=4fc2f4a377281a5f7dc0cea64515ccb8
{"code":"0002","msg":"&#25509;&#21475;&#37492;&#26435;&#22833;&#36133;","time":1533931031652}
MSG nr.:0002: interface authentication failed


Wat betreft het gevolg, als ik ooit in kan loggen, Ik heb een best mooie log gemaakt van een succesvolle inlog met je Python code van "wpietri" alleen hier staat wel veel gevoelige info in. Ik zal morgen eens kijken of ik deze kan strippen. Maar goed als stap 1 al niet lukt... :?

Acties:
  • 0 Henk 'm!

  • Vaan Banaan
  • Registratie: Februari 2001
  • Niet online

Vaan Banaan

Heeft ook Apache ontdekt

deviceId is inderdaad een random ding, dat zit wel goed.
requestId is ook zoiets, beter maak je deze later wel "random" met een md5(time) ding.

Je output klopt echter nog steeds niet.
De URL parameter waarden moeten EXACT hetzelfde zijn, als waarmee je de authSign hebt opgebouwd. Anders zal de server het request sowieso afwijzen.
Bij de PHP regels zie ik in de URL een andere authTimespan parameter waarde dan in de authSign. En ook bij account en password.

Dus authTimespan, account en password waarden 1 keer aanmaken en die ZOWEL in de authSign als voor de query parameter values gebruiken. NIET tussentijds opnieuw een tijd genereren
RSA encryptie bij account en password is geavanceerder dan een hash, Daarvan zal de encrypted tekst ook steeds anders zijn met dezelfde plaintext.

Misschien gebeurt dit, omdat bij opvragen van een $meta key de functie die daar aanhangt weer wordt aangeroepen ?

Verder gewoon volhouden, die 1005 komt in de buurt en niks mooier dan de voldoening van een eerste 0000 response.

500 "The server made a boo boo"


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Wederom bedankt voor je reactie!
Vaan Banaan schreef op zaterdag 11 augustus 2018 @ 00:33:
Je output klopt echter nog steeds niet.
De URL parameter waarden moeten EXACT hetzelfde zijn, als waarmee je de authSign hebt opgebouwd. Anders zal de server het request sowieso afwijzen.
Bij de PHP regels zie ik in de URL een andere authTimespan parameter waarde dan in de authSign. En ook bij account en password.

Dus authTimespan, account en password waarden 1 keer aanmaken en die ZOWEL in de authSign als voor de query parameter values gebruiken. NIET tussentijds opnieuw een tijd genereren
RSA encryptie bij account en password is geavanceerder dan een hash, Daarvan zal de encrypted tekst ook steeds anders zijn met dezelfde plaintext.

Misschien gebeurt dit, omdat bij opvragen van een $meta key de functie die daar aanhangt weer wordt aangeroepen ?
als je goed kijkt naar de output in mijn vorige post zijn ze wel degelijk gelijk wellicht verwarrend door dat ik PHP en Python onder elkaar heb staan. Maar de PHP plain outputs van de meta > authTimespan, account en password zijn gelijk aan de output de URL

Ik heb even een nieuwe debug output gemaakt zodat dit wat overzichtelijker is [linkje]:
code:
1
2
3
4
5
6
7
8
9
10
11
12
Python: eJUWrzRv34qFSaYkaccount=cW5ilB/p59GQvP0BBQtri0GxAg9X3dphBYPeQwaG7CLbZ9hr7pj+b+90F2UGeol+b3g12M0e3fFvgXMmsKbmzre3lpU9RkfPzy71Nh6dMkr9Sd0GmWfMXOUWZPsuSZXoTbKS+GgNbmxXEmovHjHP36lCkQ5zRPC+X6ncZV3ijNI=appCode=i_eco_eappVersion=1.3.5authTimeZone=GMT-8authTimespan=1533632529513channel=c_googleplaycountry=nldeviceId=d252b60aae03e4123236560e644a2868deviceType=1lang=enpassword=YFC50Ooo/IRFUzKxyuchtitM/GyWXtBUosoka+s1rvFqTTYTtRunjrwD9uCPJKOhxclA2b4ojn7AqfNaGchjVMTwqcLZOK7sCzGkSzQ605Oi3/Mhc5Eb9OcwFiPMnuE5x610AzeTBhtDiOuxP1FcRRndozG4XtQE6tYv9QtGa0k=requestId=35d39fec6bb359e4cab2225ca3185d8dCyu5jcR4zyK6QEPn1hdIGXB5QIDAQABMA0GC
PHP:    eJUWrzRv34qFSaYkaccount=272yDTPpIfkl2br/ivCulGaEe4mOv0it14B6ZF0siqZad5YCuRNY+REy70O5pJsNQN0zPA4AnakJpoJl5Dki/UItRfRl1JlOIJkr7fs74oI9/sPiiIaEbriXemj4Trfu39FQSEhhzK2C4r50fCbNWf5q4IwymlkmKWIE8uXdOuc=appCode=i_eco_eappVersion=1.3.5authTimeZone=GMT-8authTimespan=1533970187217channel=c_googleplaycountry=nldeviceId=5888c333257abc2c6fbb7bed22b09dc5deviceType=1lang=enpassword=sMRg3BtFOtN3ay673/qMzZBIIG1bSZ1x+Ry6xF2EHmhKCjZOZOPqIM8PiMkUItpklTkBxEroiEuEefbU7CdngbhWg2RVb1xwXneo6dPPngitPma+kafwWvYtCCjcPc4C7VVdo3l9pUKGUycQGIpZf0g/nQAoYAxsPKNlwPAGn2U=requestId=5888c333257abc2c6fbb7bed22b09dc5Cyu5jcR4zyK6QEPn1hdIGXB5QIDAQABMA0GC
Python: https://eco-nl-api.ecovacs.com/v1/private/nl/en/c670e6fc9d4753af09788e7aaa9502de/i_eco_e/1.3.5/c_googleplay/1/user/login?account=fjPqxztluo6UhPHwo87OVynFNly0eHc+f4VC6QGcWelo9kS+MN1m4/13XckxEuuPzGoI5MYiubIaWhnsRbpzHqGUD0/YkVP/4WT2jhsBXZ4tlMxX+lMKE25YncaQHRSs80aWk0sPNNKAZm5l/EWyI5Z3F1i0L9yNZYZ3rsXdTjA=&password=tOSANVu3cq1JXdEHr/JqjRGoj03X1Sm9o/iM/pxZkBMqSSgXa45Sqcs+UEmjJOEHJmLmbcxxeoUaFaiiSYZnQc/Yss0yegbXuO9pzoFBEZPmaPcxcdjAfX8okDeuhZcqzGpL3C2pftH3P8lUTGiQaBCPTIYePx+p3+LTPn3MTpU=&requestId=035ab98309f011dca9affc7aecad68ed&authTimespan=1533903118436&authTimeZone=GMT-8&authAppkey=eJUWrzRv34qFSaYk&authSign=7455460a324a0d2bf159c2f16c10f698
PHP:    https://eco-nl-api.ecovacs.com/v1/private/nl/en/5888c333257abc2c6fbb7bed22b09dc5/i_eco_e/1.3.5/c_googleplay/1/user/login?account=272yDTPpIfkl2br/ivCulGaEe4mOv0it14B6ZF0siqZad5YCuRNY+REy70O5pJsNQN0zPA4AnakJpoJl5Dki/UItRfRl1JlOIJkr7fs74oI9/sPiiIaEbriXemj4Trfu39FQSEhhzK2C4r50fCbNWf5q4IwymlkmKWIE8uXdOuc=&password=sMRg3BtFOtN3ay673/qMzZBIIG1bSZ1x+Ry6xF2EHmhKCjZOZOPqIM8PiMkUItpklTkBxEroiEuEefbU7CdngbhWg2RVb1xwXneo6dPPngitPma+kafwWvYtCCjcPc4C7VVdo3l9pUKGUycQGIpZf0g/nQAoYAxsPKNlwPAGn2U=&requestId=5888c333257abc2c6fbb7bed22b09dc5&authTimespan=1533970187217&authTimeZone=GMT-8&authAppkey=eJUWrzRv34qFSaYk&authSign=a4eaf0c747c4dc2b3945a8a272a5f070
$meta:  1533970187217
$login: 1533970187217
$meta:  272yDTPpIfkl2br/ivCulGaEe4mOv0it14B6ZF0siqZad5YCuRNY+REy70O5pJsNQN0zPA4AnakJpoJl5Dki/UItRfRl1JlOIJkr7fs74oI9/sPiiIaEbriXemj4Trfu39FQSEhhzK2C4r50fCbNWf5q4IwymlkmKWIE8uXdOuc=
$login: 272yDTPpIfkl2br/ivCulGaEe4mOv0it14B6ZF0siqZad5YCuRNY+REy70O5pJsNQN0zPA4AnakJpoJl5Dki/UItRfRl1JlOIJkr7fs74oI9/sPiiIaEbriXemj4Trfu39FQSEhhzK2C4r50fCbNWf5q4IwymlkmKWIE8uXdOuc=
$meta:  sMRg3BtFOtN3ay673/qMzZBIIG1bSZ1x+Ry6xF2EHmhKCjZOZOPqIM8PiMkUItpklTkBxEroiEuEefbU7CdngbhWg2RVb1xwXneo6dPPngitPma+kafwWvYtCCjcPc4C7VVdo3l9pUKGUycQGIpZf0g/nQAoYAxsPKNlwPAGn2U=
$login: sMRg3BtFOtN3ay673/qMzZBIIG1bSZ1x+Ry6xF2EHmhKCjZOZOPqIM8PiMkUItpklTkBxEroiEuEefbU7CdngbhWg2RVb1xwXneo6dPPngitPma+kafwWvYtCCjcPc4C7VVdo3l9pUKGUycQGIpZf0g/nQAoYAxsPKNlwPAGn2U=
{"code":"0002","msg":"&#25509;&#21475;&#37492;&#26435;&#22833;&#36133;","time":1533970187343}
MSG nr.:0002: interface authentication failed


Ik ben ook nog een beetje met tijdzones aan het spelen geweest maar mocht ook niet baten...
Vaan Banaan schreef op zaterdag 11 augustus 2018 @ 00:33:
Verder gewoon volhouden, die 1005 komt in de buurt en niks mooier dan de voldoening van een eerste 0000 response.
Komt vast goed maar het gaat hem nu echt in de details zitten...

[ Voor 0% gewijzigd door Verwijderd op 11-08-2018 12:52 . Reden: tijdzones ]


Acties:
  • +1 Henk 'm!

  • Vaan Banaan
  • Registratie: Februari 2001
  • Niet online

Vaan Banaan

Heeft ook Apache ontdekt

Hmm, ja ik zie het. Het zijn juist de Python voorbeelden die verschillen.
Maar goed, bij alle URL's komt de authSign waarde wel overeen met de query parameters waarden.

Ok, dan wordt het zo veel mogelijk het origineel imiteren.
Je kan een keer bogus account en password encrypted strings van de Python versie nemen en dan de rest wel met je programma genereren.
Als dat een verkeerd wachtwoord geeft (1005), is er iets met de RSA encryptie. Bij een 0002 toch nog ergens iets in de URL / authSign opbouw.

Afwijkingen ten opzichte van Python versie die me opvallen:
• het "wachtwoord" als md5 hash en dan pas encrypten.
• requestId niet gelijk aan deviceId, maar weer md5(time)

500 "The server made a boo boo"


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Het is dus de encryptie... ik heb de gegenereerde sleutels van de python code in de PHP gegooid en voila... een 0000 response.
{"code":"0000","msg":"操作成功","time":1534058556716,"data":{"uid":......
操作成功 > Successful operation

Dat brengt ons naar mijn encrypt() functie:

PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
include('/var/lib/symcon/externalscripts/Crypt/Crypt/RSA.php');  //http://phpseclib.sourceforge.net/
include('/var/lib/symcon/externalscripts/Crypt/File/X509.php');  //http://phpseclib.sourceforge.net/

$key = 'MIIB/TCCAWYCCQDJ7TMYJFzqYDANBgkqhkiG9w0BAQUFADBCMQswCQYDVQQGEwJjbjEVMBMGA1UEBwwMRGVmYXVsdCBDaXR5MRwwGgYDVQQKDBNEZWZhdWx0IENvbXBhbnkgTHRkMCAXDTE3MDUwOTA1MTkxMFoYDzIxMTcwNDE1MDUxOTEwWjBCMQswCQYDVQQGEwJjbjEVMBMGA1UEBwwMRGVmYXVsdCBDaXR5MRwwGgYDVQQKDBNEZWZhdWx0IENvbXBhbnkgTHRkMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDb8V0OYUGP3Fs63E1gJzJh+7iqeymjFUKJUqSD60nhWReZ+Fg3tZvKKqgNcgl7EGXp1yNifJKUNC/SedFG1IJRh5hBeDMGq0m0RQYDpf9l0umqYURpJ5fmfvH/gjfHe3Eg/NTLm7QEa0a0Il2t3Cyu5jcR4zyK6QEPn1hdIGXB5QIDAQABMA0GCSqGSIb3DQEBBQUAA4GBANhIMT0+IyJa9SU8AEyaWZZmT2KEYrjakuadOvlkn3vFdhpvNpnnXiL+cyWy2oU1Q9MAdCTiOPfXmAQt8zIvP2JC8j6yRTcxJCvBwORDyv/uBtXFxBPEC6MDfzU2gKAaHeeJUWrzRv34qFSaYkYta8canK+PSInylQTjJK9VqmjQ';

$meta['account']        = encrypt($username);
$meta['password']       = encrypt($password);

function encrypt($plaintext) {
    global $key;
    
    //$key = base64_decode($key);
    //$key = bin2hex($key);
    
    $x509 = new File_X509();
    $x509->loadX509($key);
    $pkey = $x509->getPublicKey();
    
    $rsa = new Crypt_RSA();
    $rsa->loadKey($pkey);
    $result = $rsa->encrypt($plaintext);
    //$result = hex2bin($result);
    $result = base64_encode($result);

    return $result;
} // end of function encrypt

dit maakt het extra lastig... omdat dit niet een op een te vergelijken valt... iemand tips om dit te debuggen zonder een private key of is de private key te genereren of ergens vandaan te toveren?

[ Voor 4% gewijzigd door Verwijderd op 12-08-2018 22:03 . Reden: response van API en de vertaling daarvan ]


Acties:
  • +1 Henk 'm!

  • Diecke
  • Registratie: December 2010
  • Nu online
En als je gebruik maakt van de openssl functies van PHP:

Zoiets, ongetest:
PHP:
1
2
3
4
5
6
7
function encrypt($plaintext) {
    global $key;
    $pkey = openssl_get_privatekey(base64_decode($key));
    openssl_private_encrypt ( $plaintext , $result , $pkey );
    $result = base64_encode($result);  
    return $result;
}


/edit: oh zie dat je de public key hebt, functies zijn dan hetzelfde alleen private->public

[ Voor 12% gewijzigd door Diecke op 12-08-2018 10:05 ]


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Ik ben een paar weken begonnen met de openssl functies van PHP toen ik daar op vast liep ben ik gaan googlen en zodoende kwam ik uit bij phpseclib.
het probleem is als ik de public key zoals hij in de python code staat van wpietri/sucks staat slikt openssl hem niet... ook als ik de -----BEGIN PUBLIC KEY----- en -----END PUBLIC KEY----- headers erin gooi pakt hij hem niet.

Ik heb deze test gebouwd om de boel te isoleren:
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
<?

$keyFromHost = '-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxcdSyngs75xzIw9aGPj2
PNNwDua8haR9TzsZDB9HXtY0RT6Ap2XIcqT8x05lzwtWSwTJ3N3PGVRgJ/RIxgfA
ysgoQ7eCsFGyqjOYqzMgFHn+A7nd27fRxCWAQKleQn69f0HcSrZDtl8qQlSEruDl
CvOS3nyvbOQ7/WGTMrqkDGX1aTp8yZRyXeBR4kC4ts17GCJY8FfRoZge0tzfC1de
Q+m619R3crwqyEfW3Eu2Cj4F5X7VAyl6YV4m+5msdlIm78hLrMB57lWwo3hb4dWr
qN4JnBHIeYj9/mDdZ0XPoZBzkrSf4FrBfr7NXal4OtCUnCMT0JV8+4HTMi2pKiTV
bQIDAQAB
-----END PUBLIC KEY-----';

$keyFromPython = 'MIIB/TCCAWYCCQDJ7TMYJFzqYDANBgkqhkiG9w0BAQUFADBCMQswCQYDVQQGEwJjbjEVMBMGA1UEBwwMRGVmYXVsdCBDaXR5MRwwGgYDVQQKDBNEZWZhdWx0IENvbXBhbnkgTHRkMCAXDTE3MDUwOTA1MTkxMFoYDzIxMTcwNDE1MDUxOTEwWjBCMQswCQYDVQQGEwJjbjEVMBMGA1UEBwwMRGVmYXVsdCBDaXR5MRwwGgYDVQQKDBNEZWZhdWx0IENvbXBhbnkgTHRkMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDb8V0OYUGP3Fs63E1gJzJh+7iqeymjFUKJUqSD60nhWReZ+Fg3tZvKKqgNcgl7EGXp1yNifJKUNC/SedFG1IJRh5hBeDMGq0m0RQYDpf9l0umqYURpJ5fmfvH/gjfHe3Eg/NTLm7QEa0a0Il2t3Cyu5jcR4zyK6QEPn1hdIGXB5QIDAQABMA0GCSqGSIb3DQEBBQUAA4GBANhIMT0+IyJa9SU8AEyaWZZmT2KEYrjakuadOvlkn3vFdhpvNpnnXiL+cyWy2oU1Q9MAdCTiOPfXmAQt8zIvP2JC8j6yRTcxJCvBwORDyv/uBtXFxBPEC6MDfzU2gKAaHeeJUWrzRv34qFSaYkYta8canK+PSInylQTjJK9VqmjQ';

// Key from host got by: openssl s_client -connect eco-nl-api.ecovacs.com:443 | openssl x509 -pubkey -noout
echo 'Key from Host:  '.encrypt('some test', $keyFromHost);
echo '
';
echo 'Key from Python:'.encrypt('some test', $keyFromPython);

function encrypt($plaintext, $key) {
    $pkey = openssl_get_publickey(base64_decode($key));
    openssl_public_encrypt ( $plaintext , $result , $pkey );
    $result = base64_encode($result);  
    return $result;
} 

?>

resulteert in:
Warning: openssl_public_encrypt(): key parameter is not a valid public key in /var/lib/symcon/scripts/43266.ips.php on line 23
Key from Host:

Warning: openssl_public_encrypt(): key parameter is not a valid public key in /var/lib/symcon/scripts/43266.ips.php on line 23
Key from Python:

Zo is het een paar weken geleden ook begonnen en toen heb ik dit gegoogled en kwam ik hier op uit: https://stackoverflow.com...ameter-is-not-a-valid-key zodoende kwam ik ook op phpseclib.
Als ik hem door de phpseclib gooi pikt hij hem wel... zodoende ben ik daar op berder gaan breien. Blijkbaar gaat daar dus wel iets mis. 7(8)7

Voor de vorm heb ik beide libs nog even door elkaar gebruikt en dan krijg je zoiets:
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
<?

include('/var/lib/symcon/externalscripts/Crypt/Crypt/RSA.php');
include('/var/lib/symcon/externalscripts/Crypt/File/X509.php');
    
$keyFromHost = '-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxcdSyngs75xzIw9aGPj2
PNNwDua8haR9TzsZDB9HXtY0RT6Ap2XIcqT8x05lzwtWSwTJ3N3PGVRgJ/RIxgfA
ysgoQ7eCsFGyqjOYqzMgFHn+A7nd27fRxCWAQKleQn69f0HcSrZDtl8qQlSEruDl
CvOS3nyvbOQ7/WGTMrqkDGX1aTp8yZRyXeBR4kC4ts17GCJY8FfRoZge0tzfC1de
Q+m619R3crwqyEfW3Eu2Cj4F5X7VAyl6YV4m+5msdlIm78hLrMB57lWwo3hb4dWr
qN4JnBHIeYj9/mDdZ0XPoZBzkrSf4FrBfr7NXal4OtCUnCMT0JV8+4HTMi2pKiTV
bQIDAQAB
-----END PUBLIC KEY-----';

$keyFromPython = 'MIIB/TCCAWYCCQDJ7TMYJFzqYDANBgkqhkiG9w0BAQUFADBCMQswCQYDVQQGEwJjbjEVMBMGA1UEBwwMRGVmYXVsdCBDaXR5MRwwGgYDVQQKDBNEZWZhdWx0IENvbXBhbnkgTHRkMCAXDTE3MDUwOTA1MTkxMFoYDzIxMTcwNDE1MDUxOTEwWjBCMQswCQYDVQQGEwJjbjEVMBMGA1UEBwwMRGVmYXVsdCBDaXR5MRwwGgYDVQQKDBNEZWZhdWx0IENvbXBhbnkgTHRkMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDb8V0OYUGP3Fs63E1gJzJh+7iqeymjFUKJUqSD60nhWReZ+Fg3tZvKKqgNcgl7EGXp1yNifJKUNC/SedFG1IJRh5hBeDMGq0m0RQYDpf9l0umqYURpJ5fmfvH/gjfHe3Eg/NTLm7QEa0a0Il2t3Cyu5jcR4zyK6QEPn1hdIGXB5QIDAQABMA0GCSqGSIb3DQEBBQUAA4GBANhIMT0+IyJa9SU8AEyaWZZmT2KEYrjakuadOvlkn3vFdhpvNpnnXiL+cyWy2oU1Q9MAdCTiOPfXmAQt8zIvP2JC8j6yRTcxJCvBwORDyv/uBtXFxBPEC6MDfzU2gKAaHeeJUWrzRv34qFSaYkYta8canK+PSInylQTjJK9VqmjQ';

// Key from host got by: openssl s_client -connect eco-nl-api.ecovacs.com:443 | openssl x509 -pubkey -noout
echo 'Key from Host:  '.encrypt('some test', $keyFromHost);
echo '
';
echo 'Key from Python:'.encrypt('some test', $keyFromPython);

function encrypt($plaintext, $key) {

    $x509 = new File_X509();
    $x509->loadX509($key);
    $pkey = $x509->getPublicKey();
    
    openssl_public_encrypt ( $plaintext , $result , $pkey );
    $result = base64_encode($result);  
    return $result;
} 

?>

resulteert in:
Warning: openssl_public_encrypt(): key parameter is not a valid public key in /var/lib/symcon/scripts/43266.ips.php on line 30
Key from Host:
Key from Python:d2b8E9Dky3eln7komHqjCgVbf52h9C1DoLxFVEitMGBc/3FSgPJU95qZB20ctdsFZI60u9xwqPe/UqHRQKcefGLhCXksteTcwuncb+DWg4D5tu+AY2HhNxdm/LwZ6ZpJsQkFRyZgAnd4kaHTEH0gzja80tyB3qj6UTTIOFgOVtw=

maar als ik dit weer voer aan de API, bakt die er weer niks van.....

Er zit dus iets in de X509>publickey conversie wat phpseclib (wellicht onterecht) slikt en openssl niet.
Iemand hier nog een idee over?

Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Mensen ik ben binnen! *O*

Dit is hem geworden:
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
function encrypt($plaintext) {
    global $key;
    
    $key = "-----BEGIN PUBLIC KEY-----\r\n" . chunk_split($key) . "\r\n-----END PUBLIC KEY-----";

    $x509 = new File_X509();
    $x509->loadX509($key);
    $pkey = $x509->getPublicKey();
    
    openssl_public_encrypt ( $plaintext , $result , $pkey );
    
    $result = base64_encode($result);
    return $result; 
    
} // end of function encrypt


Het deviceId moet toch random zijn. Daarom wou hij blijkbaar niet inloggen bij de pogingen in mijn vorige post.

@Diecke Bedankt voor de schop terug
@Vaan Banaan Super bedankt voor de nuchtere en scherpe blik op de zaken.

Acties:
  • 0 Henk 'm!

  • DJMaze
  • Registratie: Juni 2002
  • Niet online
Verwijderd schreef op zondag 12 augustus 2018 @ 22:02:
Er zit dus iets in de X509>publickey conversie wat phpseclib (wellicht onterecht) slikt en openssl niet.
Iemand hier nog een idee over?
PHP:
1
2
$certificate = openssl_x509_read($key);
openssl_pkey_get_public($certificate);

Een X509 PEM is wel
code:
1
-----BEGIN CERTIFICATE-----

Maak je niet druk, dat doet de compressor maar

Pagina: 1