Re: serialisation identificationmessage
Salut !
Merci pour ta réponse alexandre, ça m'a permis de voir plus claire en ce qui concerne le salt.
Maintenant j'aimerai revenir sur un point, les credentials. Si j'ai bien compris voici la procédure :
- je recois dans le hcm une clef au format X509 que j'extrait (dans un vector d'unsigned char)
- grace à la classe DofusRSA de munrek, je transforme cette clef en une clef public pour chiffrer les credentials.
J'appelle donc la méthode DofusPKeyDecrypt en lui passant directement ma clef (extraite du hcm et de taille 305 octets).
Cette méthode est censée me renvoyer une clef public pour chiffrer le salt et les identifiants.
J'ai cependant un souci, à l'appel de cette méthode, la fonction RSA_public_decrypt me retourne -1 et le code d'erreur me signal : "data greater than mod len"
Je ne comprends pas comment régler ce problème :/ .... J'ai néanmoins quelques pistes :
1) J'ai mal écrit ma clef public (contenu dans le code source de D. en dur), voici comment je l'ai mise :
Cliquez pour révéler
Cliquez pour masquer
"-----BEGIN PUBLIC KEY-----\n"
"MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA9XpbSNEUoM6niz3XTESW\n"
"J/I3+h3J+YseUIdEShxyp0nMfX8xUHUktK/QFY+V4Q3fV/pdn1PxOaxKEA8SYGNA\n"
"nc+uIal9ZGHqkbFcNF7CNp0MUFecQi5gGYpg4JPlC0onfmn6R2shSAl7M+UCVgFp\n"
"ICVrtXxocos/jg0OP/2gWFZU8AjKDo4JJP/apvubjUgufCGNXEWynRkOclMBXpAw\n"
"2IBAO6KjRdGBllPmJfYcSQq+G+9tp5nK+dzkLgITSg8JtK2tp5w+fbt5tBlCLcvC\n"
"/7CAp9t3J+ZImOO5kRw+Cn4Jd2RUMcPCd7s1JHqRXfOtuItz7xcOlqHtyLExvotf\n"
"MwIDAQAB\n"
"-----END PUBLIC KEY-----"
Est ce la bonne méthode ?
2) Il faut faire une étape sur la clef du hcm avant de l'envoyer à la méthode DofusPKeyDecrypt, et dans ce cas je dois étudier encore les sources de D2.
Pour mieux comprendre, voici la classe de munrek :
DofusRSA.h
Cliquez pour révéler
Cliquez pour masquer
/*
Copyright (C) <2013> <Munrek>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef RSA_H_
#define RSA_H_
#include "openssl/bio.h"
#include "openssl/ssl.h"
#include "openssl/err.h"
#include "openssl/rsa.h"
#include "openssl/pem.h"
#include <boost/array.hpp>
#include <fstream>
#include <iostream>
#include <sstream>
#include "base64.h"
using namespace std;
typedef unsigned char byte;
class DofusRSA {
public:
DofusRSA();
std::vector<byte> DofusPKeyDecrypt(std::vector<byte> signature);
std::vector<byte> LoginPKeyEncrypt(std::vector<byte> credentials);
void setLoginPublicKey(std::vector<byte> lPKey);
private:
std::string DofusPublicKey;
std::string LoginPublicKey;
byte *LoginPublicKeyByte;
byte *DofusPublicKeyByte;
};
#endif
DofusRSA.cpp
Cliquez pour révéler
Cliquez pour masquer
/*
Copyright (C) <2013> <Munrek>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "DofusRSA.h"
DofusRSA::DofusRSA() {
SSL_load_error_strings();
ERR_load_BIO_strings();
OpenSSL_add_all_algorithms();
stringstream SDofusPublicKey;
SDofusPublicKey << "-----BEGIN PUBLIC KEY-----\n"
"MIIBUzANBgkqhkiG9w0BAQEFAAOCAUAAMIIBOwKCATIAqpzRrvO3We7EMi9cWYqdfb3rbdinTay+\n"
"hxQ6t3dOiJLY4NITxyeIuy97yZYOojOlXS2SuJ4cCHjCeLCQO1FwOz+nynQWcBWecz2QdbHD2Kz7\n"
"mNLd2qtZyEDO76rd7LaDOxRvgs9DsH9sfnCuKLKbd725xTLc7wRfJzOH9v9rTTYVXssXe7JUpTx8\n"
"nV8yKnTiq3WpzBeZT4C3ZCR18GBBCh3NmSTbze9i2KipgZnOwBvhskVlweuqZ1KNIKsQgipBFuyw\n"
"w68RGNYaAKofMVVio4amrGpCT5MM852jpHsgJJfOUHu6md1CnvdwDPbo/PKQUI0RLb0ezE5gsPma\n"
"s39QBw+DiaibUkk1aCkBxTOFqpIbjfLM2/4qA6GPcWUJxP3vmGoeCTMBLNEiPfLqVm86QzUCAwEA\n"
"AQ==\n"
"-----END PUBLIC KEY-----";
DofusPublicKey = SDofusPublicKey.str();
}
std::vector<byte> DofusRSA::DofusPKeyDecrypt(std::vector<byte> signature) {
char * DPKey =(char *) malloc(DofusPublicKey.size());
strcpy(DPKey, DofusPublicKey.c_str());
BIO *bp_dofus = BIO_new_mem_buf(DPKey, DofusPublicKey.size());
RSA *my_rsa = PEM_read_bio_RSA_PUBKEY(bp_dofus, NULL, NULL, NULL);
byte *inputSignature, *outputSignature;
inputSignature = (byte*) malloc(5000);
outputSignature = (byte*) malloc(5000);
inputSignature = reinterpret_cast<byte*> (&signature[0]);
int buflen = RSA_public_decrypt(signature.size(), inputSignature, outputSignature, my_rsa, RSA_PKCS1_PADDING);
std::vector<byte> outputSignatureVector(outputSignature, outputSignature+buflen);
return outputSignatureVector;
}
std::vector<byte> DofusRSA::LoginPKeyEncrypt(std::vector<byte> credentials) {
char * LoginPublicKeyByte = (char *) malloc(LoginPublicKey.size());
strcpy(LoginPublicKeyByte, LoginPublicKey.c_str());
BIO *bp_login = BIO_new_mem_buf(LoginPublicKeyByte, -1);
RSA *my_second_rsa = PEM_read_bio_RSA_PUBKEY(bp_login, NULL, NULL, NULL);
byte *pinputCredentials, *poutputCredentials;
pinputCredentials = (byte*) malloc(5000);
poutputCredentials = (byte*) malloc(5000);
pinputCredentials = reinterpret_cast<byte*> (&credentials[0]);
int buflen = RSA_public_encrypt(credentials.size(), pinputCredentials, poutputCredentials, my_second_rsa, RSA_PKCS1_PADDING);
std::vector<byte> outputCredentialsVector(poutputCredentials, poutputCredentials+buflen);
return outputCredentialsVector;
}
void DofusRSA::setLoginPublicKey(std::vector<byte> lPKey) {
const std::string lPKeyStr(lPKey.begin(), lPKey.end());
std::string lPKeyStrEnc = base64_encode(reinterpret_cast<const unsigned char*>(lPKeyStr.c_str()), lPKeyStr.length());
stringstream lPKeyStrEncFor;
for(int i=0; i!= lPKeyStrEnc.length(); i++){
lPKeyStrEncFor << lPKeyStrEnc;
if((i+1)%76==0){
if(i!=0) lPKeyStrEncFor << "\n";
}
}
stringstream SlPKeyStrEnc;
SlPKeyStrEnc << "-----BEGIN PUBLIC KEY-----" << "\n" << lPKeyStrEncFor.str() << "\n" << "-----END PUBLIC KEY-----";
LoginPublicKey = SlPKeyStrEnc.str();
}
base64.h
Cliquez pour révéler
Cliquez pour masquer
#include <string>
std::string base64_encode(unsigned char const* , unsigned int len);
std::string base64_decode(std::string const& s);
base64.cpp
Cliquez pour révéler
Cliquez pour masquer
/*
base64.cpp and base64.h
Copyright (C) 2004-2008 René Nyffenegger
This source code is provided 'as-is', without any express or implied
warranty. In no event will the author be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this source code must not be misrepresented; you must not
claim that you wrote the original source code. If you use this source code
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original source code.
3. This notice may not be removed or altered from any source distribution.
René Nyffenegger rene.nyffenegger@adp-gmbh.ch
*/
#include "base64.h"
#include <iostream>
static const std::string base64_chars =
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz"
"0123456789+/";
static inline bool is_base64(unsigned char c) {
return (isalnum(c) || (c == '+') || (c == '/'));
}
std::string base64_encode(unsigned char const* bytes_to_encode, unsigned int in_len) {
std::string ret;
int i = 0;
int j = 0;
unsigned char char_array_3[3];
unsigned char char_array_4[4];
while (in_len--) {
char_array_3[i++] = *(bytes_to_encode++);
if (i == 3) {
char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
char_array_4[3] = char_array_3[2] & 0x3f;
for(i = 0; (i <4) ; i++)
ret += base64_chars[char_array_4];
i = 0;
}
}
if (i)
{
for(j = i; j < 3; j++)
char_array_3[j] = '\0';
char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
char_array_4[3] = char_array_3[2] & 0x3f;
for (j = 0; (j < i + 1); j++)
ret += base64_chars[char_array_4[j]];
while((i++ < 3))
ret += '=';
}
return ret;
}
std::string base64_decode(std::string const& encoded_string) {
int in_len = encoded_string.size();
int i = 0;
int j = 0;
int in_ = 0;
unsigned char char_array_4[4], char_array_3[3];
std::string ret;
while (in_len-- && ( encoded_string[in_] != '=') && is_base64(encoded_string[in_])) {
char_array_4[i++] = encoded_string[in_]; in_++;
if (i ==4) {
for (i = 0; i <4; i++)
char_array_4 = base64_chars.find(char_array_4);
char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);
char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);
char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3];
for (i = 0; (i < 3); i++)
ret += char_array_3;
i = 0;
}
}
if (i) {
for (j = i; j <4; j++)
char_array_4[j] = 0;
for (j = 0; j <4; j++)
char_array_4[j] = base64_chars.find(char_array_4[j]);
char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);
char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);
char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3];
for (j = 0; (j < i - 1); j++) ret += char_array_3[j];
}
return ret;
}