encrypt password and account number
* the encryption uses a unique machine key, this means that if anyone steals config.otml with a saved password, he will not be able to decrypt the password without the machine UUID key * the encrypt uses a simple XOR encryption method, encoded with base64 and adler32 summing
This commit is contained in:
parent
296f2a17c4
commit
e5000fa577
|
@ -40,7 +40,7 @@ local function tryLogin(charInfo, tries)
|
||||||
|
|
||||||
CharacterList.destroyLoadBox()
|
CharacterList.destroyLoadBox()
|
||||||
|
|
||||||
g_game.loginWorld(EnterGame.account, EnterGame.password, charInfo.worldName, charInfo.worldHost, charInfo.worldPort, charInfo.characterName)
|
g_game.loginWorld(G.account, G.password, charInfo.worldName, charInfo.worldHost, charInfo.worldPort, charInfo.characterName)
|
||||||
|
|
||||||
loadBox = displayCancelBox(tr('Please wait'), tr('Connecting to game server...'))
|
loadBox = displayCancelBox(tr('Please wait'), tr('Connecting to game server...'))
|
||||||
connect(loadBox, { onCancel = function()
|
connect(loadBox, { onCancel = function()
|
||||||
|
@ -81,6 +81,10 @@ function CharacterList.init()
|
||||||
connect(g_game, { onConnectionError = onGameConnectionError })
|
connect(g_game, { onConnectionError = onGameConnectionError })
|
||||||
connect(g_game, { onGameStart = CharacterList.destroyLoadBox })
|
connect(g_game, { onGameStart = CharacterList.destroyLoadBox })
|
||||||
connect(g_game, { onGameEnd = CharacterList.showAgain })
|
connect(g_game, { onGameEnd = CharacterList.showAgain })
|
||||||
|
|
||||||
|
if G.characters then
|
||||||
|
CharacterList.create(G.characters, G.premDays)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function CharacterList.terminate()
|
function CharacterList.terminate()
|
||||||
|
@ -100,7 +104,9 @@ function CharacterList.terminate()
|
||||||
end
|
end
|
||||||
|
|
||||||
function CharacterList.create(characters, premDays)
|
function CharacterList.create(characters, premDays)
|
||||||
CharacterList.show()
|
G.characters = characters
|
||||||
|
G.premDays = premDays
|
||||||
|
|
||||||
characterList:destroyChildren()
|
characterList:destroyChildren()
|
||||||
local accountStatusLabel = charactersWindow:getChildById('accountStatusLabel')
|
local accountStatusLabel = charactersWindow:getChildById('accountStatusLabel')
|
||||||
|
|
||||||
|
|
|
@ -3,8 +3,6 @@ EnterGame = { }
|
||||||
-- private variables
|
-- private variables
|
||||||
local loadBox
|
local loadBox
|
||||||
local enterGame
|
local enterGame
|
||||||
local motdNumber
|
|
||||||
local motdMessage
|
|
||||||
local motdButton
|
local motdButton
|
||||||
local enterGameButton
|
local enterGameButton
|
||||||
|
|
||||||
|
@ -29,15 +27,15 @@ local function onError(protocol, message, connectionError)
|
||||||
end
|
end
|
||||||
|
|
||||||
local function onMotd(protocol, motd)
|
local function onMotd(protocol, motd)
|
||||||
motdNumber = tonumber(motd:sub(0, motd:find("\n")))
|
G.motdNumber = tonumber(motd:sub(0, motd:find("\n")))
|
||||||
motdMessage = motd:sub(motd:find("\n") + 1, #motd)
|
G.motdMessage = motd:sub(motd:find("\n") + 1, #motd)
|
||||||
motdButton:show()
|
motdButton:show()
|
||||||
end
|
end
|
||||||
|
|
||||||
local function onCharacterList(protocol, characters, premDays)
|
local function onCharacterList(protocol, characters, premDays)
|
||||||
if enterGame:getChildById('rememberPasswordBox'):isChecked() then
|
if enterGame:getChildById('rememberPasswordBox'):isChecked() then
|
||||||
Settings.set('account', EnterGame.account)
|
Settings.set('account', g_crypt.encrypt(G.account))
|
||||||
Settings.set('password', EnterGame.password)
|
Settings.set('password', g_crypt.encrypt(G.password))
|
||||||
Settings.set('autologin', enterGame:getChildById('autoLoginBox'):isChecked())
|
Settings.set('autologin', enterGame:getChildById('autoLoginBox'):isChecked())
|
||||||
else
|
else
|
||||||
clearAccountFields()
|
clearAccountFields()
|
||||||
|
@ -47,11 +45,12 @@ local function onCharacterList(protocol, characters, premDays)
|
||||||
loadBox = nil
|
loadBox = nil
|
||||||
|
|
||||||
CharacterList.create(characters, premDays)
|
CharacterList.create(characters, premDays)
|
||||||
|
CharacterList.show()
|
||||||
|
|
||||||
local lastMotdNumber = Settings.getNumber("motd")
|
local lastMotdNumber = Settings.getNumber("motd")
|
||||||
if motdNumber and motdNumber ~= lastMotdNumber then
|
if G.motdNumber and G.motdNumber ~= lastMotdNumber then
|
||||||
Settings.set("motd", motdNumber)
|
Settings.set("motd", motdNumber)
|
||||||
local motdBox = displayInfoBox(tr('Message of the day'), motdMessage)
|
local motdBox = displayInfoBox(tr('Message of the day'), G.motdMessage)
|
||||||
connect(motdBox, { onOk = CharacterList.show })
|
connect(motdBox, { onOk = CharacterList.show })
|
||||||
CharacterList.hide()
|
CharacterList.hide()
|
||||||
end
|
end
|
||||||
|
@ -65,8 +64,12 @@ function EnterGame.init()
|
||||||
motdButton:hide()
|
motdButton:hide()
|
||||||
Keyboard.bindKeyDown('Ctrl+G', EnterGame.openWindow)
|
Keyboard.bindKeyDown('Ctrl+G', EnterGame.openWindow)
|
||||||
|
|
||||||
local account = Settings.get('account')
|
if G.motdNumber then
|
||||||
local password = Settings.get('password')
|
motdButton:show()
|
||||||
|
end
|
||||||
|
|
||||||
|
local account = g_crypt.decrypt(Settings.get('account'))
|
||||||
|
local password = g_crypt.decrypt(Settings.get('password'))
|
||||||
local host = Settings.get('host')
|
local host = Settings.get('host')
|
||||||
local port = Settings.get('port')
|
local port = Settings.get('port')
|
||||||
local autologin = Settings.getBoolean('autologin')
|
local autologin = Settings.getBoolean('autologin')
|
||||||
|
@ -119,14 +122,14 @@ function EnterGame.openWindow()
|
||||||
end
|
end
|
||||||
|
|
||||||
function EnterGame.doLogin()
|
function EnterGame.doLogin()
|
||||||
EnterGame.account = enterGame:getChildById('accountNameTextEdit'):getText()
|
G.account = enterGame:getChildById('accountNameTextEdit'):getText()
|
||||||
EnterGame.password = enterGame:getChildById('accountPasswordTextEdit'):getText()
|
G.password = enterGame:getChildById('accountPasswordTextEdit'):getText()
|
||||||
EnterGame.host = enterGame:getChildById('serverHostTextEdit'):getText()
|
G.host = enterGame:getChildById('serverHostTextEdit'):getText()
|
||||||
EnterGame.port = tonumber(enterGame:getChildById('serverPortTextEdit'):getText())
|
G.port = tonumber(enterGame:getChildById('serverPortTextEdit'):getText())
|
||||||
EnterGame.hide()
|
EnterGame.hide()
|
||||||
|
|
||||||
Settings.set('host', EnterGame.host)
|
Settings.set('host', G.host)
|
||||||
Settings.set('port', EnterGame.port)
|
Settings.set('port', G.port)
|
||||||
|
|
||||||
local protocolLogin = ProtocolLogin.create()
|
local protocolLogin = ProtocolLogin.create()
|
||||||
protocolLogin.onError = onError
|
protocolLogin.onError = onError
|
||||||
|
@ -140,9 +143,9 @@ function EnterGame.doLogin()
|
||||||
EnterGame.show()
|
EnterGame.show()
|
||||||
end })
|
end })
|
||||||
|
|
||||||
protocolLogin:login(EnterGame.host, EnterGame.port, EnterGame.account, EnterGame.password)
|
protocolLogin:login(G.host, G.port, G.account, G.password)
|
||||||
end
|
end
|
||||||
|
|
||||||
function EnterGame.displayMotd()
|
function EnterGame.displayMotd()
|
||||||
displayInfoBox(tr('Message of the day'), motdMessage)
|
displayInfoBox(tr('Message of the day'), G.motdMessage)
|
||||||
end
|
end
|
||||||
|
|
|
@ -4,6 +4,9 @@ importStyle = g_ui.importStyle
|
||||||
importFont = g_fonts.importFont
|
importFont = g_fonts.importFont
|
||||||
setDefaultFont = g_fonts.setDefaultFont
|
setDefaultFont = g_fonts.setDefaultFont
|
||||||
|
|
||||||
|
-- G is used as a global table to save variables in memory between reloads
|
||||||
|
G = G or {}
|
||||||
|
|
||||||
function loadUI(otui, parent)
|
function loadUI(otui, parent)
|
||||||
local otuiFilePath = resolvepath(otui, 2)
|
local otuiFilePath = resolvepath(otui, 2)
|
||||||
return g_ui.loadUI(otuiFilePath, parent)
|
return g_ui.loadUI(otuiFilePath, parent)
|
||||||
|
|
|
@ -171,6 +171,8 @@ SET(framework_SOURCES ${framework_SOURCES}
|
||||||
|
|
||||||
# framework util
|
# framework util
|
||||||
${CMAKE_CURRENT_LIST_DIR}/util/color.cpp
|
${CMAKE_CURRENT_LIST_DIR}/util/color.cpp
|
||||||
|
${CMAKE_CURRENT_LIST_DIR}/util/crypt.cpp
|
||||||
|
${CMAKE_CURRENT_LIST_DIR}/util/rsa.cpp
|
||||||
|
|
||||||
# framework core
|
# framework core
|
||||||
${CMAKE_CURRENT_LIST_DIR}/core/adaptativeframecounter.cpp
|
${CMAKE_CURRENT_LIST_DIR}/core/adaptativeframecounter.cpp
|
||||||
|
@ -189,7 +191,6 @@ SET(framework_SOURCES ${framework_SOURCES}
|
||||||
${CMAKE_CURRENT_LIST_DIR}/net/inputmessage.cpp
|
${CMAKE_CURRENT_LIST_DIR}/net/inputmessage.cpp
|
||||||
${CMAKE_CURRENT_LIST_DIR}/net/outputmessage.cpp
|
${CMAKE_CURRENT_LIST_DIR}/net/outputmessage.cpp
|
||||||
${CMAKE_CURRENT_LIST_DIR}/net/protocol.cpp
|
${CMAKE_CURRENT_LIST_DIR}/net/protocol.cpp
|
||||||
${CMAKE_CURRENT_LIST_DIR}/net/rsa.cpp
|
|
||||||
${CMAKE_CURRENT_LIST_DIR}/net/server.cpp
|
${CMAKE_CURRENT_LIST_DIR}/net/server.cpp
|
||||||
|
|
||||||
# framework platform
|
# framework platform
|
||||||
|
|
|
@ -33,6 +33,7 @@
|
||||||
#include <framework/core/modulemanager.h>
|
#include <framework/core/modulemanager.h>
|
||||||
#include <framework/core/module.h>
|
#include <framework/core/module.h>
|
||||||
#include <framework/sound/soundmanager.h>
|
#include <framework/sound/soundmanager.h>
|
||||||
|
#include <framework/util/crypt.h>
|
||||||
|
|
||||||
void Application::registerLuaFunctions()
|
void Application::registerLuaFunctions()
|
||||||
{
|
{
|
||||||
|
@ -46,6 +47,10 @@ void Application::registerLuaFunctions()
|
||||||
g_lua.bindGlobalFunction("colortostring", [](const Color& v) { return stdext::to_string(v); });
|
g_lua.bindGlobalFunction("colortostring", [](const Color& v) { return stdext::to_string(v); });
|
||||||
g_lua.bindGlobalFunction("sizetostring", [](const Size& v) { return stdext::to_string(v); });
|
g_lua.bindGlobalFunction("sizetostring", [](const Size& v) { return stdext::to_string(v); });
|
||||||
|
|
||||||
|
g_lua.registerStaticClass("g_crypt");
|
||||||
|
g_lua.bindClassStaticFunction("g_crypt", "encrypt", Crypt::encrypt);
|
||||||
|
g_lua.bindClassStaticFunction("g_crypt", "decrypt", Crypt::decrypt);
|
||||||
|
|
||||||
// Event
|
// Event
|
||||||
g_lua.registerClass<Event>();
|
g_lua.registerClass<Event>();
|
||||||
g_lua.bindClassMemberFunction<Event>("cancel", &Event::cancel);
|
g_lua.bindClassMemberFunction<Event>("cancel", &Event::cancel);
|
||||||
|
|
|
@ -21,7 +21,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "inputmessage.h"
|
#include "inputmessage.h"
|
||||||
#include "rsa.h"
|
#include <framework/util/rsa.h>
|
||||||
|
|
||||||
InputMessage::InputMessage()
|
InputMessage::InputMessage()
|
||||||
{
|
{
|
||||||
|
@ -105,7 +105,7 @@ void InputMessage::setHeaderSize(uint16 size)
|
||||||
bool InputMessage::readChecksum()
|
bool InputMessage::readChecksum()
|
||||||
{
|
{
|
||||||
uint32_t receivedCheck = getU32();
|
uint32_t receivedCheck = getU32();
|
||||||
uint32 checksum = stdext::generate_adler_checksum(m_buffer + m_readPos, getUnreadSize());
|
uint32 checksum = stdext::adler32(m_buffer + m_readPos, getUnreadSize());
|
||||||
return receivedCheck == checksum;
|
return receivedCheck == checksum;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -21,7 +21,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <framework/net/outputmessage.h>
|
#include <framework/net/outputmessage.h>
|
||||||
#include "rsa.h"
|
#include <framework/util/rsa.h>
|
||||||
|
|
||||||
OutputMessage::OutputMessage()
|
OutputMessage::OutputMessage()
|
||||||
{
|
{
|
||||||
|
@ -96,7 +96,7 @@ void OutputMessage::encryptRSA(int size, const std::string& key)
|
||||||
|
|
||||||
void OutputMessage::writeChecksum()
|
void OutputMessage::writeChecksum()
|
||||||
{
|
{
|
||||||
uint32 checksum = stdext::generate_adler_checksum(m_buffer + m_headerPos, m_messageSize);
|
uint32 checksum = stdext::adler32(m_buffer + m_headerPos, m_messageSize);
|
||||||
assert(m_headerPos - 4 >= 0);
|
assert(m_headerPos - 4 >= 0);
|
||||||
m_headerPos -= 4;
|
m_headerPos -= 4;
|
||||||
stdext::writeLE32(m_buffer + m_headerPos, checksum);
|
stdext::writeLE32(m_buffer + m_headerPos, checksum);
|
||||||
|
|
|
@ -28,7 +28,7 @@
|
||||||
|
|
||||||
namespace stdext {
|
namespace stdext {
|
||||||
|
|
||||||
inline uint32 generate_adler_checksum(uint8 *buffer, uint16 size) {
|
inline uint32 adler32(const uint8 *buffer, uint16 size) {
|
||||||
register uint32 a = 1, b = 0, tlen;
|
register uint32 a = 1, b = 0, tlen;
|
||||||
while(size > 0) {
|
while(size > 0) {
|
||||||
tlen = size > 5552 ? 5552 : size;
|
tlen = size > 5552 ? 5552 : size;
|
||||||
|
@ -57,9 +57,9 @@ inline uint32 to_power_of_two(uint32 v) {
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline uint16 readLE16(uchar *addr) { return (uint16)addr[1] << 8 | addr[0]; }
|
inline uint16 readLE16(const uchar *addr) { return (uint16)addr[1] << 8 | addr[0]; }
|
||||||
inline uint32 readLE32(uchar *addr) { return (uint32)readLE16(addr + 2) << 16 | readLE16(addr); }
|
inline uint32 readLE32(const uchar *addr) { return (uint32)readLE16(addr + 2) << 16 | readLE16(addr); }
|
||||||
inline uint64 readLE64(uchar *addr) { return (uint64)readLE32(addr + 4) << 32 | readLE32(addr); }
|
inline uint64 readLE64(const uchar *addr) { return (uint64)readLE32(addr + 4) << 32 | readLE32(addr); }
|
||||||
|
|
||||||
inline void writeLE16(uchar *addr, uint16 value) { addr[1] = value >> 8; addr[0] = (uint8)value; }
|
inline void writeLE16(uchar *addr, uint16 value) { addr[1] = value >> 8; addr[0] = (uint8)value; }
|
||||||
inline void writeLE32(uchar *addr, uint32 value) { writeLE16(addr + 2, value >> 16); writeLE16(addr, (uint16)value); }
|
inline void writeLE32(uchar *addr, uint32 value) { writeLE16(addr + 2, value >> 16); writeLE16(addr, (uint16)value); }
|
||||||
|
|
|
@ -161,7 +161,7 @@ inline std::string date_time_string() {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Convert decimal to hexadecimal
|
/// Convert decimal to hexadecimal
|
||||||
inline std::string dec_to_hex(unsigned int num) {
|
inline std::string dec_to_hex(uint64 num) {
|
||||||
std::string str;
|
std::string str;
|
||||||
std::ostringstream o;
|
std::ostringstream o;
|
||||||
o << std::hex << num;
|
o << std::hex << num;
|
||||||
|
@ -170,8 +170,8 @@ inline std::string dec_to_hex(unsigned int num) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Convert hexadecimal to decimal
|
/// Convert hexadecimal to decimal
|
||||||
inline unsigned int hex_to_dec(const std::string& str) {
|
inline uint64 hex_to_dec(const std::string& str) {
|
||||||
unsigned int num;
|
uint64 num;
|
||||||
std::istringstream i(str);
|
std::istringstream i(str);
|
||||||
i >> std::hex >> num;
|
i >> std::hex >> num;
|
||||||
return num;
|
return num;
|
||||||
|
|
|
@ -0,0 +1,161 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2010-2012 OTClient <https://github.com/edubart/otclient>
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "crypt.h"
|
||||||
|
#include <framework/stdext/math.h>
|
||||||
|
|
||||||
|
#include <boost/uuid/uuid.hpp>
|
||||||
|
#include <boost/functional/hash.hpp>
|
||||||
|
|
||||||
|
static const std::string base64_chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
||||||
|
static inline bool is_base64(unsigned char c) { return (isalnum(c) || (c == '+') || (c == '/')); }
|
||||||
|
|
||||||
|
std::string Crypt::base64Encode(const std::string& decoded_string)
|
||||||
|
{
|
||||||
|
std::string ret;
|
||||||
|
int i = 0;
|
||||||
|
int j = 0;
|
||||||
|
uint8 char_array_3[3];
|
||||||
|
uint8 char_array_4[4];
|
||||||
|
int pos = 0;
|
||||||
|
int len = decoded_string.size();
|
||||||
|
|
||||||
|
while(len--) {
|
||||||
|
char_array_3[i++] = decoded_string[pos++];
|
||||||
|
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]];
|
||||||
|
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 Crypt::base64Decode(const std::string& encoded_string)
|
||||||
|
{
|
||||||
|
int len = encoded_string.size();
|
||||||
|
int i = 0;
|
||||||
|
int j = 0;
|
||||||
|
int in_ = 0;
|
||||||
|
uint8 char_array_4[4], char_array_3[3];
|
||||||
|
std::string ret;
|
||||||
|
|
||||||
|
while(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[i] = base64_chars.find(char_array_4[i]);
|
||||||
|
|
||||||
|
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];
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string Crypt::xorCrypt(const std::string& buffer, const std::string& key)
|
||||||
|
{
|
||||||
|
std::string out;
|
||||||
|
out.resize(buffer.size());
|
||||||
|
register size_t i, j=0;
|
||||||
|
for(i=0;i<buffer.size();++i) {
|
||||||
|
out[i] = buffer[i] ^ key[j++];
|
||||||
|
if(j >= key.size())
|
||||||
|
j = 0;
|
||||||
|
}
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string Crypt::genUUIDKey()
|
||||||
|
{
|
||||||
|
boost::hash<boost::uuids::uuid> uuid_hasher;
|
||||||
|
std::size_t hash = uuid_hasher(boost::uuids::uuid());
|
||||||
|
std::string key;
|
||||||
|
key.assign((const char *)&hash, sizeof(hash));
|
||||||
|
return key;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string Crypt::encrypt(const std::string& decrypted_string)
|
||||||
|
{
|
||||||
|
std::string tmp = "0000" + decrypted_string;
|
||||||
|
uint32 sum = stdext::adler32((const uint8*)decrypted_string.c_str(), decrypted_string.size());
|
||||||
|
stdext::writeLE32((uint8*)&tmp[0], sum);
|
||||||
|
std::string encrypted = base64Encode(xorCrypt(tmp, genUUIDKey()));
|
||||||
|
return encrypted;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string Crypt::decrypt(const std::string& encrypted_string)
|
||||||
|
{
|
||||||
|
std::string decoded = base64Decode(encrypted_string);
|
||||||
|
std::string tmp = xorCrypt(base64Decode(encrypted_string), genUUIDKey());
|
||||||
|
if(tmp.length() >= 4) {
|
||||||
|
uint32 readsum = stdext::readLE32((const uint8*)tmp.c_str());
|
||||||
|
std::string decrypted_string = tmp.substr(4);
|
||||||
|
uint32 sum = stdext::adler32((const uint8*)decrypted_string.c_str(), decrypted_string.size());
|
||||||
|
if(readsum == sum)
|
||||||
|
return decrypted_string;
|
||||||
|
}
|
||||||
|
return std::string();
|
||||||
|
}
|
|
@ -0,0 +1,38 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2010-2012 OTClient <https://github.com/edubart/otclient>
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef CRYPT_H
|
||||||
|
#define CRYPT_H
|
||||||
|
|
||||||
|
#include "../stdext/types.h"
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
namespace Crypt {
|
||||||
|
std::string base64Encode(const std::string& decoded_string);
|
||||||
|
std::string base64Decode(const std::string& encoded_string);
|
||||||
|
std::string xorCrypt(const std::string& buffer, const std::string& key);
|
||||||
|
std::string genUUIDKey();
|
||||||
|
std::string encrypt(const std::string& decrypted_string);
|
||||||
|
std::string decrypt(const std::string& encrypted_string);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
Loading…
Reference in New Issue