C/C++ AuthentificationFrame : Calcul credentials

Inscrit
1 Mars 2020
Messages
18
Reactions
12
#1
Bonjour, je travaille actuellement sur un bot socket pour dofus 2.54 (dernière version) en c++ et je bloque au moment de l'authentification.
Il me semble faire tout bien comme il faut mais le serveur le répond un IdentificationFailedMessage lorsque je lui envoie mon IdentificationMessage. A part pour les credentials, je suis sûr à 99% que mon message contient les bonnes valeurs. Le cas des credentials est plus compliqué car je peux pas comparer avec mes messages avec ceux envoyés par un client classique, à cause du cryptage RSA. Je vous demande donc de l'aide pour savoir ce que j'ai de faux dans mon calcul des credentials.

Lorsque je me connecte au seveur, je reçois un HelloConnectMessage, avec lequel je récupère la clé publique du serveur (à l'aide de la verification Key du client) et le salt.

Ensuite, je contruis une liste contenant : le Salt, une clé AES de 32 octets générés aléatoirement, la taille du login sur un octet, le login et enfin le password.
Je met tout à la suite sous forme hexadécimale, puis je rajoute en préfixe : 0002XXXXXXXXXXXXXXXX00 avec XX correspondant à un octet aléatoire. Celà correspond (?) à la fonction pkcs1pad de la classe RsaKey (02 correspond au padType).

Code:
      private function pkcs1pad(src:ByteArray, end:int, n:uint, type:uint = 2) : ByteArray
      {
         var rng:Random = null;
         var x:int = 0;
         var out:ByteArray = new ByteArray();
         var p:uint = src.position;
         end = Math.min(end,src.length,p + n - 11);
         src.position = end;
         var i:int = end - 1;
         while(i >= p && n > 11)
         {
            out[--n] = src[i--];
         }
         out[_loc10_] = 0;
         if(type == 2)
         {
            rng = new Random();
            x = 0;
            while(n > 2)
            {
               do
               {
                  x = rng.nextByte();
               }
               while(x == 0);
              
               out[--n] = x;
            }
         }
         else
         {
            while(n > 2)
            {
               out[--n] = 255;
            }
         }
         out[_loc11_] = type;
         var _loc12_:* = --n;
         out[_loc12_] = 0;
         return out;
      }
Cela me donne donc une chaine de cette forme (avec salt = k861416r4#V?yJ}VZviB9]L~R%&j-`p):

Code:
0002527b7cdf7b97d536006b383631343136723423563f794a7d565a766942395d4c7e5225266a2d607029e00b0f3ac5945858d8f7b36199084bd181d34bdde28ece35094b1485e2e9bbc308757365726e616d6570617373776f7264
Enfin, je transforme cette chaine en BigInt et je l'encypte avec la clé RSA : c = (b^E)%N (avec c les credentials, b le BigInt et E et N les caractéristiques de la clé RSA publique du serveur)

J'obtiens donc les credentials, de taille 256, que j'incorpore dans mon IdentificationMessage pour obtenir un message de ce type (les credentials commencent à l'octet 0x4D et finissent à l'octet 0x14C) :

Code:
                   00 00 00 12 00 00 00 03 01 14 01 02
0040   36 10 00 00 01 58 00 00 02 66 72 80 02 12 f3 c5
0050   f4 77 fa 4c a2 9c 22 1c 24 b9 13 b1 f2 2c 1c 2a
0060   62 16 77 a7 0b 8d fe 3d d7 8e f8 df 71 c4 0a 0f
0070   58 85 eb a9 12 fe 73 cc c5 76 b7 2a 80 21 1a b9
0080   09 9e cb ba e4 70 50 05 14 dc 38 df 51 43 3c cd
0090   85 47 aa ab 42 ca af 9b 93 ba af a9 99 d0 b7 01
00a0   91 b0 1f 89 91 31 a5 1e e0 a5 0f 18 f3 ee 11 9e
00b0   aa c8 6a 72 ea f0 51 2e 19 56 9c ca 5a 4f 1e 52
00c0   78 21 31 65 22 34 93 30 d2 b1 89 f8 44 78 57 00
00d0   50 5d 77 4b 96 c7 a4 cf 80 6e 33 91 92 10 fa 59
00e0   8a 58 4b cc dc d6 38 86 32 29 94 98 ed 08 1e b9
00f0   82 92 49 a4 ac 12 b3 71 d8 c5 a6 40 28 4c c0 03
0100   35 86 f6 0b 4f f1 eb 31 9d dd 75 aa 33 a6 0f 4f
0110   91 64 22 f0 4c 25 7d b5 97 7c d5 9b 6c e1 cf fd
0120   1f d7 79 e4 79 96 85 75 b3 78 1c 60 91 22 a8 2a
0130   ba 66 8e 2e 4d 6b ef 1e 8e 2c 9c 02 41 da e9 61
0140   04 21 1b 59 3a 4c 9d a5 5e 62 07 64 10 00 00 00
0150   00 00
J'envoie aussi mon ClientKeyMessage, mais tout ce que je reçois du serveur sont 2 packets de type 10 (LoginQueueStatusMessage) et un paquet de type 20 (IdentificationFailed) qui a pour erreur : 2; WRONG_CREDENTIALS.

Où est mon erreur ? Je me demande si le password est hashé avant le calcul des crédentials mais ca n'a pas l'air d'être le cas.
Sinon je pense m'être trompé sur la compréhension de la fonction pkcs1pad, mais dans ce cas je ne vois vraiment pas ce que j'ai mal compris.
Si vous avez besoin de précisions, n'hésitez sutout pas à me demander.

Merci d'avance ! :)
 

BlueDream

Administrateur
Membre du personnel
Inscrit
8 Decembre 2012
Messages
2 010
Reactions
149
#2
Hello,

Déjà, quelle est la publicKey que tu utilises ?
Est-elle à jour ? Tu pourras trouver la dernière version dans les données binaires de l'Invoker dans JPEXS.

Ensuite ton code en CPP me semble assez léger,
Tu as essayé de regarder comment fonctionnait les RSA sur les bots actuels ?
Cherche sur le forum, t'es ni le premier, ni le dernier.

https://cadernis.fr/index.php?threads/rsa-cipherrsa.1384/#post-16285
 
Inscrit
1 Mars 2020
Messages
18
Reactions
12
#3
Merci pour ta réponse !

J'utilise cette clé là :

Code:
-----BEGIN PUBLIC KEY-----
MIIBUzANBgkqhkiG9w0BAQEFAAOCAUAAMIIBOwKCATIAgucoka9J2PXcNdjcu6CuDmgteIMB+rih
2UZJIuSoNT/0J/lEKL/W4UYbDA4U/6TDS0dkMhOpDsSCIDpO1gPG6+6JfhADRfIJItyHZflyXNUj
WOBG4zuxc/L6wldgX24jKo+iCvlDTNUedE553lrfSU23Hwwzt3+doEfgkgAf0l4ZBez5Z/ldp9it
2NH6/2/7spHm0Hsvt/YPrJ+EK8ly5fdLk9cvB4QIQel9SQ3JE8UQrxOAx2wrivc6P0gXp5Q6bHQo
ad1aUp81Ox77l5e8KBJXHzYhdeXaM91wnHTZNhuWmFS3snUHRCBpjDBCkZZ+CxPnKMtm2qJIi57R
slALQVTykEZoAETKWpLBlSm92X/eXY2DdGf+a7vju9EigYbX0aXxQy2Ln2ZBWmUJyZE8B58CAwEA
AQ==
-----END PUBLIC KEY-----
C'est celle que j'ai trouvé dans les données binaires de la dernière version de dofus.

Je vois pas bien ce que tu veux dire par "code assez léger". Après avoir regardé le code, il me semble qu'il n'y a beaucoup plus d'étapes, mais je me trompe surement (d'où ce post ^^).

J'ai pas mal cherché mais ce que je vois c'est que bcp de monde utilise des bibiothèques RSA, ce que je ne voulais pas faire à la base parce que je sais que je vais avoir du mal à l'adapter pour imiter ce que fais dofus.

Je pense que je vais me tourner vers Crypto++ pour voir ce que je peux faire. Merci pour ton lien.
C'est frustrant parce que je ne sais pas ce que j'ai de faux. Je t'avoue que j'ai passé pas mal de temps sur ce code et j'aurais bien aimé trouver la solution à mon pb au lieu de me lancer sur une solution complètement différente.

Si quelqu'un vois ce que j'ai pu faire de faux, je suis toujours preneur.
 

BlueDream

Administrateur
Membre du personnel
Inscrit
8 Decembre 2012
Messages
2 010
Reactions
149
#4
Peut-être que tu auras plus de chance sur discord,
On a quelques devs CPP, j'en fait partie, mais je peux pas du tout t'aider la dessus,
Jamais fait de RSA ou de formule trop complexe dans cette techno.
 
Inscrit
22 Juillet 2018
Messages
81
Reactions
12
#5
Utilise une lib qui a le padding de dofus, RSA n'est pas aussi simple que ton implémentation :)
 
Inscrit
1 Mars 2020
Messages
18
Reactions
12
#6
Utilise une lib qui a le padding de dofus, RSA n'est pas aussi simple que ton implémentation :)
C'est ce que je vais faire ^^ Je suis entrain de prendre en main crypto++ en ce moment même!

Le truc qui me frustre c'est que j'ai quand meme réussi à décoder la clé publique et à avoir des valeurs qui font sens. J'arrive meme à appliquer la fonction DER sur le message décrypté pour avoir des valeurs de N et E correctes (je crois). J'imagine qu'encoder un message doit être plus compliqué que le décoder :teeth:
 
Inscrit
30 Mars 2020
Messages
3
Reactions
0
#7
Salut,
Je suis aussi sur le projet d'un bot socket depuis quelque jours. Je m'apprêtes à commencer la génération de l'IdentificationMessage mais je bloque. As-tu avancé? Me conseille-tu de commencer comme toi en essayant de refaire les fonctions : _decrypt (de RSAKey),
cipherRsa (de AuthentificationManager) ... et certainement d'autres ?
Ou as-tu continué et réussi avec Crypto++ ?
De plus Crypto++ propose effectivement le padding pkcs1 mais sous plusieurs versions, propose-t-il effectivement la même fonction de padding qu'utilise le launcher ?

Merci
 
Dernière édition:
Inscrit
1 Mars 2020
Messages
18
Reactions
12
#8
Salut,
Effectivement j'ai un peu avancé et j'ai réussi à générer mon IdentificationMesasge.
D'abord, ne refais SURTOUT pas la fonction _decrypt. c'est ce que j'ai voulu faire à la base, mais c'est inutile. J'ai perdu énormément de temps à cause de ca.
Au final j'ai utilisé les biliothèques de OpenSSL, car je n'arrivais pas à faire fonctionner Crypto++ pour une raison qui m'échappe.
La version du padding utilisée est pkcs v1.5 (la constante utilisée par openssl est RSA_PKCS1_PADDING).
Voici un topic qui m'avais bien aidé : https://cadernis.fr/index.php?threads/rsa-encryption-des-credentials.2154/
 
Inscrit
30 Mars 2020
Messages
3
Reactions
0
#9
Merci beaucoup ! Je vais voir ça, bonne chance pour la suite de ton projet !
 
Inscrit
13 Avril 2016
Messages
7
Reactions
0
#10
Bonjour, j'ai exactement le meme probleme que toi@LaCulotte j'utilise openssl mais je galere un peu je sais pas comment ca fonctionne ^^'.
Est ce que tu pourrais me guidé un peu ? et aussi qu'elle version d'openssl utilise tu ?
Cordialement,
 
Inscrit
1 Mars 2020
Messages
18
Reactions
12
#11
Je peux t'aider, t'as une question en particulier? j'utilise la version 1.1.1f d'openssl, il me semble que c'est la dernière version.
 
Haut Bas