Ultima modifica:
Salve,la release non è mia,ma proviene da epvp. Ciò che sto per pubblicare potrebbe tornarvi utile.
Condivido il nuovo key-exchange e packetencryption (Utili per un clientlessbot)
Testo originale
cipher_gf.h
cipher_gf.cpp
Condivido il nuovo key-exchange e packetencryption (Utili per un clientlessbot)
Testo originale
Some informations about:
- I used Cryptopp 5.6.2(Download it and compile the cryptolib and link it to your project)
- Add cryptopp header to your project to make the following .h and .cpp working
Usage:
If you connect to the server, the server(after handshake phase) will send an 65 byte public key within a 261byte packet.
- I used Cryptopp 5.6.2(Download it and compile the cryptolib and link it to your project)
- Add cryptopp header to your project to make the following .h and .cpp working
Usage:
If you connect to the server, the server(after handshake phase) will send an 65 byte public key within a 261byte packet.
Codice:
#define HEADER_KEY_EXCHANGE 0xFB
CCipher cipObj;
PacketKeyAgreement keyServer = getPacket<PacketKeyAgreement>();
PacketKeyAgreement keyClient;
uint32_t dataLength = keyServer.wDataLength;
size_t agreedLength = cipObj.Prepare(keyClient.data, &dataLength);
if (cipObj.Activate(true, agreedLength, keyServer.data, keyServer.wDataLength))
{
keyClient.bHeader = HEADER_KEY_EXCHANGE;
keyClient.wAgreedLength = agreedLength;
keyClient.wDataLength = keyServer.wDataLength;
if (!sendToServer((char*)&keyClient, sizeof(keyClient)))
{
//ErrorEvent(typeid(keyClient).name());
}
else
{
cout << "[CRYPTO]: Verschlüsselung aktiviert" << endl;
}
}
cipher_gf.h
Codice:
#include "stdafx.h"
#ifndef __CIPHER__H__
#define __CIPHER__H__
class CKeyAgreement;
class CCipher
{
private:
bool m_bActivated;
CryptoPP::SymmetricCipher* m_pkEncoder;
CryptoPP::SymmetricCipher* m_pkDecoder;
CKeyAgreement* m_pkKeyAgreement;
public:
CCipher();
~CCipher();
uint32_t Prepare(void* pBuffer, uint32_t* puLength);
bool Activate(bool bPolarity, uint32_t uAgreedLength, const void* c_pBuffer, uint32_t uLength);
inline bool Encrypt(void* pBuffer, uint32_t uLength)
{
if(m_bActivated)
{
m_pkEncoder->ProcessData(reinterpret_cast<uint8_t*>(pBuffer), reinterpret_cast<uint8_t*>(pBuffer), uLength);
}
return true;
}
inline bool Decrypt(void* pBuffer, uint32_t uLength)
{
if(m_bActivated)
{
m_pkDecoder->ProcessData(reinterpret_cast<uint8_t*>(pBuffer), reinterpret_cast<uint8_t*>(pBuffer), uLength);
}
return true;
}
inline bool Activated() const
{
return m_bActivated;
}
inline void SetActivated(bool bActivated)
{
m_bActivated = bActivated;
}
private:
bool SetUp(bool bPolarity);
};
#endif
cipher_gf.cpp
Codice:
#include "stdafx.h"
#include "Cipher.h"
#include <string>
#include <cstdlib>
#include "cryptopp/osrng.h"
#include "cryptopp/eccrypto.h"
#include "cryptopp/asn.h"
#include "cryptopp/integer.h"
#include "cryptopp/aes.h"
#include "cryptopp/secblock.h"
#include "cryptopp/oids.h"
using std::cout;
using std::cerr;
using std::endl;
using std::string;
using std::runtime_error;
using std::exit;
using CryptoPP::AutoSeededRandomPool;
using CryptoPP::AutoSeededX917RNG;
using CryptoPP::AES;
using CryptoPP::ECP;
using CryptoPP::ECDH;
using CryptoPP::SecByteBlock;
using CryptoPP::OID;
using namespace CryptoPP::ASN1;
using CryptoPP::Integer;
class CKeyAgreement
{
private:
CryptoPP::ECDH < CryptoPP::ECP >::Domain dhA;
CryptoPP::SecByteBlock m_kPubKey;
CryptoPP::SecByteBlock m_kPrivKey;
CryptoPP::SecByteBlock m_kShared;
public:
CKeyAgreement()
{
}
~CKeyAgreement()
{
}
uint32_t Prepare(void* pBuffer, uint32_t* puLength)
{
CryptoPP::OID CURVE = secp256r1();
AutoSeededX917RNG<AES> rng;
dhA.AccessGroupParameters().Initialize(CURVE);
m_kPrivKey.New(dhA.PrivateKeyLength());
m_kPubKey.New(dhA.PublicKeyLength());
dhA.GenerateKeyPair(rng, m_kPrivKey, m_kPubKey);
*puLength = m_kPubKey.SizeInBytes();
uint8_t* pbBuffer = reinterpret_cast<uint8_t*>(pBuffer);
memcpy(pbBuffer, m_kPubKey.BytePtr(), m_kPubKey.SizeInBytes());
return m_kPrivKey.SizeInBytes();
}
bool Agree(uint32_t uAgreedLength, const void* c_pBuffer, uint32_t uLength)
{
m_kShared.New(uAgreedLength);
const uint8_t* pbBuffer = reinterpret_cast<const uint8_t*>(c_pBuffer);
if(!dhA.Agree(m_kShared, m_kPrivKey, /*&otherPublicKey[0]*/pbBuffer))
{
std::cout << "agree failed" << std::endl;
return false;
}
return true;
}
CryptoPP::SecByteBlock& GetShared()
{
return m_kShared;
}
};
struct BlockCipherAlgorithm
{
BlockCipherAlgorithm() {}
virtual ~BlockCipherAlgorithm() {}
static BlockCipherAlgorithm* Pick(int hint);
virtual int GetBlockSize() const = 0;
virtual int GetDefaultKeyLength() const = 0;
virtual int GetIVLength() const = 0;
virtual CryptoPP::SymmetricCipher* CreateEncoder(const uint8_t* pbKey, uint32_t uKeyLength, const uint8_t* pbIv) const = 0;
virtual CryptoPP::SymmetricCipher* CreateDecoder(const uint8_t* pbKey, uint32_t uKeyLength, const uint8_t* pbIv) const = 0;
};
template<class T>
struct BlockCipherDetail : public BlockCipherAlgorithm
{
BlockCipherDetail() {}
virtual ~BlockCipherDetail() {}
virtual int GetBlockSize() const { return T::BLOCKSIZE; }
virtual int GetDefaultKeyLength() const { return T::DEFAULT_KEYLENGTH; }
virtual int GetIVLength() const { return T::IV_LENGTH; }
virtual CryptoPP::SymmetricCipher* CreateEncoder(const uint8_t* pbKey, uint32_t uKeyLength, const uint8_t* pbIv) const
{
return new typename CryptoPP::CTR_Mode<T>::Encryption(pbKey, uKeyLength, pbIv);
}
virtual CryptoPP::SymmetricCipher* CreateDecoder(const uint8_t* pbKey, uint32_t uKeyLength, const uint8_t* pbIv) const
{
return new typename CryptoPP::CTR_Mode<T>::Decryption(pbKey, uKeyLength, pbIv);
}
};
BlockCipherAlgorithm* BlockCipherAlgorithm::Pick(int hint)
{
BlockCipherAlgorithm* detail;
int selector2 = hint;
selector2 &= 0x8000000F;
if(selector2 & 0x80000000)
{
selector2--;
selector2 |= 0xFFFFFFF6;
selector2++;
}
selector2--;
switch (selector2)
{
case 0:
detail = new BlockCipherDetail<CryptoPP::DES_EDE2>();//
break;
case 1:
detail = new BlockCipherDetail<CryptoPP::SEED>();//
break;
case 2:
detail = new BlockCipherDetail<CryptoPP::SHACAL2>();//
break;
case 3:
detail = new BlockCipherDetail<CryptoPP::IDEA>();//
break;
case 4:
detail = new BlockCipherDetail<CryptoPP::Camellia>();//
break;
case 5:
detail = new BlockCipherDetail<CryptoPP::TEA>();//
break;
case 6:
detail = new BlockCipherDetail<CryptoPP::Blowfish>();//
break;
case 7:
detail = new BlockCipherDetail<CryptoPP::RC5>();//
break;
case 8:
detail = new BlockCipherDetail<CryptoPP::SKIPJACK>();//
break;
case 9:
detail = new BlockCipherDetail<CryptoPP::Rijndael>();//
break;
case 10:
detail = new BlockCipherDetail<CryptoPP::MARS>();//
break;
case 11:
detail = new BlockCipherDetail<CryptoPP::CAST256>();//
break;
case 12:
detail = new BlockCipherDetail<CryptoPP::Twofish>();//
break;
case 13:
detail = new BlockCipherDetail<CryptoPP::RC6>();//
break;
case 14:
detail = new BlockCipherDetail<CryptoPP::Serpent>();//
break;
default:
detail = new BlockCipherDetail<CryptoPP::Twofish>();//
break;
}
return detail;
}
CCipher::CCipher() : m_bActivated(false), m_pkEncoder(nullptr), m_pkDecoder(nullptr), m_pkKeyAgreement(new CKeyAgreement())
{
}
CCipher::~CCipher()
{
if(m_pkKeyAgreement)
{
delete m_pkKeyAgreement;
}
if(m_pkEncoder)
{
delete m_pkEncoder;
}
if(m_pkDecoder)
{
delete m_pkDecoder;
}
}
uint32_t CCipher::Prepare(void* pBuffer, uint32_t* puLength)
{
if(m_pkKeyAgreement)
{
delete m_pkKeyAgreement;
}
m_pkKeyAgreement = new CKeyAgreement();
uint32_t uAgreedLength = m_pkKeyAgreement->Prepare(pBuffer, puLength);
if(uAgreedLength == 0)
{
delete m_pkKeyAgreement;
m_pkKeyAgreement = nullptr;
}
return uAgreedLength;
}
bool CCipher::Activate(bool bPolarity, uint32_t uAgreedLength, const void* c_pBuffer, uint32_t uLength)
{
bool bResult = false;
if(m_pkKeyAgreement->Agree(uAgreedLength, c_pBuffer, uLength))
{
bResult = __SetUp(bPolarity);
}
delete m_pkKeyAgreement;
m_pkKeyAgreement = nullptr;
return bResult;
}
bool CCipher::__SetUp(bool bPolarity)
{
const CryptoPP::SecByteBlock& kShared = m_pkKeyAgreement->GetShared();
if(kShared.size() < 2)
{
return false;
}
int32_t iHint0 = kShared.BytePtr()[*(kShared.BytePtr()) % kShared.size()];
int32_t iHint1 = kShared.BytePtr()[*(kShared.BytePtr() + 1) % kShared.size()];
BlockCipherAlgorithm* pkDetail0 = BlockCipherAlgorithm::Pick(iHint0);
BlockCipherAlgorithm* pkDetail1 = BlockCipherAlgorithm::Pick(iHint1);
uint32_t uKeyLength0 = pkDetail0->GetDefaultKeyLength();
uint32_t uIvLength0 = pkDetail0->GetBlockSize();
if(kShared.size() < uKeyLength0 || kShared.size() < uIvLength0)
{
delete pkDetail0;
delete pkDetail1;
return false;
}
uint32_t uKeyLength1 = pkDetail1->GetDefaultKeyLength();
uint32_t uIvLength1 = pkDetail1->GetBlockSize();
if(kShared.size() < uKeyLength1 || kShared.size() < uIvLength1)
{
delete pkDetail0;
delete pkDetail1;
return false;
}
CryptoPP::SecByteBlock kKey0(uKeyLength0), kIv0(uIvLength0);
CryptoPP::SecByteBlock kKey1(uKeyLength1), kIv1(uIvLength1);
uint32_t uOffset = 0;
kKey0.Assign(kShared, uKeyLength0);
uOffset = uKeyLength0;
uOffset = std::min<uint32_t>(uKeyLength0, kShared.size() - uKeyLength1);
kKey1.Assign(kShared.BytePtr() + uOffset, uKeyLength1);
uOffset = kShared.size() - uIvLength0;
kIv0.Assign(kShared.BytePtr() + uOffset, uIvLength0);
uOffset = (uOffset < uIvLength1 ? 0 : uOffset - uIvLength1);
kIv1.Assign(kShared.BytePtr() + uOffset, uIvLength1);
if(bPolarity)
{
m_pkEncoder = pkDetail1->CreateEncoder(kKey1, kKey1.size(), kIv1);
m_pkDecoder = pkDetail0->CreateDecoder(kKey0, kKey0.size(), kIv0);
}
else
{
m_pkEncoder = pkDetail0->CreateEncoder(kKey0, kKey0.size(), kIv0);
m_pkDecoder = pkDetail1->CreateDecoder(kKey1, kKey1.size(), kIv1);
}
delete pkDetail0;
delete pkDetail1;
SetActivated(true);
return true;
}