RSA setPublicKey

Inscrit
5 Juillet 2013
Messages
39
Reactions
0
#1
Bonjour !

J'ai commencé il y a peu a essayer de comprendre comment crypter ce fameux "credentials" pour le paquet numéro 4 (identificationMessage).

Et j'ai plus ou moins tout compris jusqu’à ce que j'arrive a la fonction setPublicKey.

petit rappel de la fonction :

Code:
public function setPublicKey(param1:Vector.<int>) : void {
         var _loc2_:ByteArray = new ByteArray();
         var _loc3_:* = 0;
         while(_loc3_ < param1.length)
         {
            _loc2_.writeByte(param1[_loc3_]);
            _loc3_++;
         }
         _loc2_.position = 0;
         var _loc4_:ByteArray = new ByteArray();
         var _loc5_:RSAKey = PEM.readRSAPublicKey((new this._verifyKey() as ByteArray).readUTFBytes((new this._verifyKey() as ByteArray).length));
         _loc5_.verify(_loc2_,_loc4_,_loc2_.length);
         this._publicKey = "-----BEGIN PUBLIC KEY-----\n" + Base64.encodeByteArray(_loc4_) + "-----END PUBLIC KEY-----";
      }
Mon problème est ici :

Code:
var _loc5_:RSAKey = PEM.readRSAPublicKey((new this._verifyKey() as ByteArray).readUTFBytes((new this._verifyKey() as ByteArray).length));
La fonction readRSAPublicKey est censée "purifier" la clé qui lui est envoyée en paramètre, notamment en lui enlevant son header et son footer, puis en le décodant (car elle est en base64). Tout cela grâce a la fonction extractBinary.



1) Je ne comprends pas trop ce qui est envoyé en paramètre à readRSAPublicKey ?
2) Je tombe un peu plus loin sur une classe nommée DER, qlq sait-il a quoi elle sert ?


J'attends votre avis :)
 
Inscrit
5 Juillet 2013
Messages
39
Reactions
0
#2
Bonjour, j'ai évolué depuis il y a ... 10 minutes :p

J'ai découvert ceci :

Clef PEM : Clef base 64 qui à une "forme"
Clef DER : Juste une suite de bytes

Mais je suis toujours bloqué au niveau de ce que reçois readRSAPublicKey en paramètre :/

des idées ??
 

BlueDream

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

ne t'embête pas à traduire la fonction d'ankama, la clé public du RSA est static. La voici :p
Private Const _RSAPublicKey As String = "MIIBUzANBgkqhkiG9w0BAQEFAAOCAUAAMIIBOwKCATIAqpzRrvO3We7EMi9cWYqdfb3rbdinTay+" + "hxQ6t3dOiJLY4NITxyeIuy97yZYOojOlXS2SuJ4cCHjCeLCQO1FwOz+nynQWcBWecz2QdbHD2Kz7" + "mNLd2qtZyEDO76rd7LaDOxRvgs9DsH9sfnCuKLKbd725xTLc7wRfJzOH9v9rTTYVXssXe7JUpTx8" + "nV8yKnTiq3WpzBeZT4C3ZCR18GBBCh3NmSTbze9i2KipgZnOwBvhskVlweuqZ1KNIKsQgipBFuyw" + "w68RGNYaAKofMVVio4amrGpCT5MM852jpHsgJJfOUHu6md1CnvdwDPbo/PKQUI0RLb0ezE5gsPma" + "s39QBw+DiaibUkk1aCkBxTOFqpIbjfLM2/4qA6GPcWUJxP3vmGoeCTMBLNEiPfLqVm86QzUCAwEA" + "AQ=="
 
Inscrit
5 Juillet 2013
Messages
39
Reactions
0
#4
OK donc si j'ai bien tout compris :

1) Le serveur nous envoie une clé session (paquet numéro 3)
2) J'utilise la clé publique pour décrypter la clé session
3) J'utilise la clé session pour crypter le salt, le mot de passe et le login => credentials

Mais la clé session est envoyée sous forme d'un tableau de vector<int> :/ Donc je vais quand même devoir m'amuser à ré-écrire les fonction de dofus pour pouvoir en tirer une clé correcte ?

Ou bien j'ai tout faux et je dois juste crypter le salt, le mot de passe et le login avec la clé publique, mais dans ce cas, à quoi me sert la clé reçue dans le paquet numéro 3 ?
 

BlueDream

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

Votre première théorie est la Bonne,

vous recevez d'une part une clé publique qui nous donnera ensuite une clé privé qui nous permettra de crypter mot de passe, login, salt.

N'oubliez pas de faire la conversion en Byte().

Cordialement
 
Inscrit
5 Juillet 2013
Messages
39
Reactions
0
#6
Merci beaucoup pour ces réponses ;)

Je vais me pencher sur le fonctionnement de la RSA, car il me semble que je doive encore trouver un moyen de convertir ces tableaux de int en une clé utilisable ^^'.

J'ai vu que cipherRsa convertissait son message crypté en tableau de int, je vais donc essayer de ré-écrire cette partie à l'envers, puis décoder le résultat en utilisant RSA.

Je vous tiens au courant :)
 

BlueDream

Administrateur
Membre du personnel
Inscrit
8 Decembre 2012
Messages
2 010
Reactions
149
#7
N'hésitez à demander de l'aide si vous bloquez.
 
Inscrit
5 Juillet 2013
Messages
39
Reactions
0
#8
Bonjour,

J'ai réussi a créer un authentifiactionFrame plus ou moins correct aujourd'hui, mais une erreur subsiste :

Ma fonction rsa ne semble pas pouvoir traiter la clé publique que vous m'avez donnée. Effectivement, chaque fois que je tente de crypter/décrypter quelque chose avec, mon programme plante. J'ai donc essayé de décrypter des messages plus basiques, mais rien a faire. L'erreur vient donc de la clé elle même; peut être dois-je encore modifier la clé avant de l'utiliser ?

j'attends vos conseil avec impatience .
 
Inscrit
5 Juillet 2013
Messages
39
Reactions
0
#9
J'ai encore évolué depuis tantôt,
Il semblerait donc que dofus utilise un format de clé non adapté a ma classe rsa, a savoir X509.

Mais je ne sais pas trop à quoi correspond ce format. Je vais essayer de tout convertir en PEM pour voir si ça marche, mais je doute que cela changera quelque chose. Peut-être est-ce ma librairie qui n'est pas adaptée ?

Si quelqu'un rencontre le même problème, ou connait la réponse, n'hésitez pas a en faire part sur ce topic ;)

merci .
 

BlueDream

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

oui en effet la clé est au format X509, mais tu peux facilement la décoder à l'aide de la librairie suivant:
System.Security.Cryptography
Code:
Dim RSA As RSACryptoServiceProvider = DecodeX509PublicKey(Convert.FromBase64String(_RSAPublicKey))
:p

Et ma clé public fonctionne parfaitement je l'utilise en ce moment :)

Cordialement
 
Inscrit
15 Avril 2011
Messages
457
Reactions
1
#11
Je profite de ce topic pour poser une question qui est du même sujet.
Je ne comprends pas comment, à partir du fichier HelloConnectMessage, on arrive dans le fichier AuthentificationMessage ? J'ai beau suivre les import, je ne trouve pas...
 
Inscrit
5 Juillet 2013
Messages
39
Reactions
0
#12
Bonjour,

Je profite de ce topic pour poser une question qui est du même sujet.
Je ne comprends pas comment, à partir du fichier HelloConnectMessage, on arrive dans le fichier AuthentificationMessage ? J'ai beau suivre les import, je ne trouve pas...
Le fichier AuthentificationMessage n’existe pas si je ne m'abuse, je pense que tu veux parler du fichier AuthentificationFrame.

Vois cela comme ton fichier central pour la connexion au serveur. Il va recevoir les paquets, les analyser, puis déduire quel classe est la plus adaptée.

Un exemple :

1)Le programme va recevoir le paquet numéro 3 : helloConnectMessage
2)Il va le dé-sérialiser en utilisant la classe adaptée
3)Il va créer une nouvelle instance de la classe IdentificationMessage à laquelle il va passer les argument nécessaire (parse, key)

Comme rien ne vaut un exemple :

Code:
case msg  is  HelloConnectMessage:
               hcmsg = HelloConnectMessage(msg);
               AuthentificationManager.getInstance().setPublicKey(hcmsg.key);
               AuthentificationManager.getInstance().setSalt(hcmsg.salt);
               ConnectionsHandler.getConnection().send(AuthentificationManager.getInstance().getIdentificationMessage());    
               KernelEventsManager.getInstance().processCallback(HookList.ConnectionTimerStart);
               TimeManager.getInstance().reset();
               return true;
J’espère que j'aurai pu t'aider un peu ;)
 
Inscrit
15 Avril 2011
Messages
457
Reactions
1
#13
Oups, désolé j'ai mal lu. Je parlais d'AuthentificationManager, celui dont tu parlais précédemment.
En fait, j'ai désérialisé le paquet 3, puis quand je veux sérialiser le paquet 4, j'ai aucun moyen de trouver le fichier qui s'occupe du RSA. C'est là que j'ai vu ton topic, et que j'ai pu trouvé le fichier AuthentificationManager (en faisant une recherche de la fonction setPublicKey). Mais si AuthentificationManager n'est pas linké dans le fichier IdentificationMessage, comment il y arrive ?
 

BlueDream

Administrateur
Membre du personnel
Inscrit
8 Decembre 2012
Messages
2 010
Reactions
149
#14
Peut être car en réalité c'est AuthentificationManager qui est linké dans les frames de dofus, ensuite on appel Identification Message.

Cordialement
 
Inscrit
5 Juillet 2013
Messages
39
Reactions
0
#16
Bonjour,

J'ai loupé un épisode là avec ce AuthentificationManager...
La structure est assez simple en réalité :

AuthentificationFrame s'occupe de réceptionner les paquets et de les envoyer au classe "message" correspondantes, tel que ProtocolRequired ou encore HelloConnectMessage.
AuthentificationManager quand a lui ajoute quelques fonction intéressantes qui seront utilisées dans AuthentificationFrame.

Reprenons le code de tout a l'heure :

le authentificationFrame décrypte le header et utilise l' id sous forme de switch();

ainsi quand l'id du paquet est égal a HelloConnectMessage :

Code:
case msg  is  HelloConnectMessage:
               hcmsg = HelloConnectMessage(msg);
               AuthentificationManager.getInstance().setPublicKey(hcmsg.key);
               AuthentificationManager.getInstance().setSalt(hcmsg.salt);
               ConnectionsHandler.getConnection().send(AuthentificationManager.getInstance().getIdentificationMessage());
               KernelEventsManager.getInstance().processCallback(HookList.ConnectionTimerStart);
               TimeManager.getInstance().reset();
               return true;
1) AuthentificationFrame lance une nouvelle instance de HelloConnectMessage (donc décrypte le salt et la key )
2) AuthentificationFrame fait appel à AuthentificationManager pour adapter le salt et "purifier" la clef.
3) AuthentificationFrame fait appel à AuthentificationManager pour lancer une nouvelle instance de identificationMessage
à laquelle il envoie les bonnes données en paramètre.

le *3 se passe dans cette fonction :

Code:
public function getIdentificationMessage() : IdentificationMessage {
         var _loc1_:IdentificationMessage = null;
         var _loc2_:String = null;
         var _loc3_:Array = null;
         var _loc4_:IdentificationAccountForceMessage = null;
         if(this._lva.username.indexOf("|") == -1)
         {
            _loc1_ = new IdentificationMessage();
            if(this._lva  is  LoginValidationWithTicketAction || (this.nextToken))
            {
               _loc2_ = this.nextToken?this.nextToken:LoginValidationWithTicketAction(this._lva).ticket;
               this.nextToken = null;
               this.ankamaPortalKey = this.cipherMd5String(_loc2_);
               _loc1_.initIdentificationMessage(_loc1_.version,XmlConfig.getInstance().getEntry("config.lang.current"),this.cipherRsa("   ",_loc2_,this._certificate),this._lva.serverId,this._lva.autoSelectServer,!(this._certificate == null),true);
            }
            else
            {
               this.ankamaPortalKey = this.cipherMd5String(this._lva.password);
               _loc1_.initIdentificationMessage(_loc1_.version,XmlConfig.getInstance().getEntry("config.lang.current"),this.cipherRsa(this._lva.username,this._lva.password,this._certificate),this._lva.serverId,this._lva.autoSelectServer,!(this._certificate == null),false);
            }
            _loc1_.version.initVersionExtended(BuildInfos.BUILD_VERSION.major,BuildInfos.BUILD_VERSION.minor,BuildInfos.BUILD_VERSION.release,AirScanner.isStreamingVersion()?70000:BuildInfos.BUILD_REVISION,BuildInfos.BUILD_PATCH,BuildInfos.BUILD_VERSION.buildType,AirScanner.isStreamingVersion()?ClientInstallTypeEnum.CLIENT_STREAMING:ClientInstallTypeEnum.CLIENT_BUNDLE,AirScanner.hasAir()?ClientTechnologyEnum.CLIENT_AIR:ClientTechnologyEnum.CLIENT_FLASH);
            return _loc1_;
         }
         this.ankamaPortalKey = this.cipherMd5String(this._lva.password);
         _loc3_ = this._lva.username.split("|");
         _loc4_ = new IdentificationAccountForceMessage();
         _loc4_.initIdentificationAccountForceMessage(_loc4_.version,XmlConfig.getInstance().getEntry("config.lang.current"),this.cipherRsa(_loc3_[0],this._lva.password,this._certificate),this._lva.serverId,this._lva.autoSelectServer,!(this._certificate == null),false,0,_loc3_[1]);
         _loc4_.version.initVersionExtended(BuildInfos.BUILD_VERSION.major,BuildInfos.BUILD_VERSION.minor,BuildInfos.BUILD_VERSION.release,BuildInfos.BUILD_REVISION,BuildInfos.BUILD_PATCH,BuildInfos.BUILD_VERSION.buildType,AirScanner.isStreamingVersion()?ClientInstallTypeEnum.CLIENT_STREAMING:ClientInstallTypeEnum.CLIENT_BUNDLE,AirScanner.hasAir()?ClientTechnologyEnum.CLIENT_AIR:ClientTechnologyEnum.CLIENT_FLASH);
         return _loc4_;
      }

Donc pour résumer, authentificationManager contient les fonctions utilisées dans notre authentificationFrame ;)
 

BlueDream

Administrateur
Membre du personnel
Inscrit
8 Decembre 2012
Messages
2 010
Reactions
149
#17
Sinon de ton côté Moufett, tu t'en sorts ?
 
Inscrit
5 Juillet 2013
Messages
39
Reactions
0
#18
Oui merci a toi ;)

J'ai eu du mal a récupérer correctement la clef du certificat x509, mais je pense que la partie RSA devrais bientôt être bouclée :)
Reste a savoir si je convertis correctement les credentials en tableau de int, mais je ne me fais pas trop de soucis a ce propos .

Je vous tiens au courant .
 
Inscrit
15 Avril 2011
Messages
457
Reactions
1
#19
Merci Moufett d'avoir pris un peu de temps pour m'expliquer. En effet, je n'avais rien lu sur AuthentificationFrame. Et grâce à toi, je comprends mieux maintenant. Je vais essayer de voir ce que je peux faire.

Pour la 1), c'est quoi l'intérêt d'agrandir le salt avec des espaces ?

Dois-je me préoccuper des deux dernières instructions : KernelEventsManager.getInstance().processCallback(HookList.ConnectionTimerStart); et TimeManager.getInstance().reset(); ?
 
Inscrit
5 Juillet 2013
Messages
39
Reactions
0
#20
Pour tout te dire, je ne sais pas moi même et je n'y ai pas fait attention :) Peut être que le serveur envoie des salt plus petits que 32 de temps en temps (mais ce n'est qu'une hypothèse)

En ce qui concerne les deux dernières instructions je n'y ai pas vraiment fait attention et je ne penses pas que tu doives t'en préoccuper ;)
 
Haut Bas