Undetected [GF]KeyAgreement - PacketEncryption

Stato
Discussione chiusa ad ulteriori risposte.

Slat3

Utente Palladium
16 Maggio 2013
2,359
214
4,495
1,793
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
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.
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;
}
 
Si ma leva quel codice messo in modo centrale, è cancerogeno
 
Stato
Discussione chiusa ad ulteriori risposte.