Jump to content
Returning Members: Password Reset Required ×

Release: Era of Faith Packet Cipher


Recommended Posts

Posted

Background

This implementation was once published to an underground forum for Conquer Online by Lateralus. Though it works for Conquer Online v4217 (Alpha), it also works for the alpha client of Era of Faith. The code below is publicly published with permission (granted way back in 2012).

Code

public class Legacy
{
   private byte[] _cryptKey1, _cryptKey2, _cryptKey3, _cryptKey4;
   private CryptCounter _decryptCounter;
   private CryptCounter _encryptCounter;
   public bool Exchanged { get; private set; }

   public Legacy()
   {
Exchanged = false;

       _decryptCounter = new CryptCounter();
       _encryptCounter = new CryptCounter();

       CreateKeys();
   }

   public void Decrypt(byte[] Data)
   {
for (int i = 0; i < Data.Length; i++)
{
    Data[i] ^= Exchanged ? (byte)(_cryptKey4[_decryptCounter.Key2] ^ _cryptKey3[_decryptCounter.Key1]) : Data[i] ^= (byte)(_cryptKey2[_decryptCounter.Key2] ^ _cryptKey1[_decryptCounter.Key1]);
    _decryptCounter.Increment();
}
   }

   public unsafe void Decrypt(byte* lpData, int Length)
   {
for (int i = 0; i < Length; i++)
{
    lpData[i] ^= Exchanged ? (byte)(_cryptKey4[_decryptCounter.Key2] ^ _cryptKey3[_decryptCounter.Key1]) : lpData[i] ^= (byte)(_cryptKey2[_decryptCounter.Key2] ^ _cryptKey1[_decryptCounter.Key1]);
    _decryptCounter.Increment();
}
   }

   public void Encrypt(byte[] Data)
   {
for (int i = 0; i < Data.Length; i++)
{
    Data[i] ^= (byte)(_cryptKey1[_encryptCounter.Key1] ^ _cryptKey2[_encryptCounter.Key2]);
    _encryptCounter.Increment();
}
   }

   public unsafe void Encrypt(byte* lpData, int Length)
   {
for (int i = 0; i < Length; i++)
{
    lpData[i] ^= (byte)(_cryptKey1[_encryptCounter.Key1] ^ _cryptKey2[_encryptCounter.Key2]);
    _encryptCounter.Increment();
}
   }

   private void CreateKeys()
   {
_cryptKey1 = new byte[0x100];
_cryptKey2 = new byte[0x100];

byte iKey1 = 0x1F;
byte iKey2 = 0x3F;
for (int i = 0; i < 0x100; i++)
{
    _cryptKey1[i] = iKey1;
    _cryptKey2[i] = iKey2;
    iKey1 = (byte)(((byte)(iKey1 << 5) + 0xFD) * iKey1 + 7);
    iKey2 = (byte)((iKey2 * 0x7A - 0x31) * iKey2 - 0x1B);
}
   }

   public void GenerateKeys(uint Token, uint AccountID)
   {
_cryptKey3 = new byte[0x100];
_cryptKey4 = new byte[0x100];

       int tmpkey1 = (int)((Token + AccountID) ^ 0x4321 ^ Token);
       int tmpkey2 = tmpkey1 * tmpkey1;
       byte[] tmp1 = BitConverter.GetBytes(tmpkey1);
       byte[] tmp2 = BitConverter.GetBytes(tmpkey2);
       for (int i = 0; i < 256; i++)
       {
           _cryptKey3[i] = (byte)(_cryptKey1[i] ^ tmp1[i % 4]);
           _cryptKey4[i] = (byte)(_cryptKey2[i] ^ tmp2[i % 4]);
       }

       Exchanged = true;
   }

   private class CryptCounter
   {
       private int m_Counter = 0;

public byte Key2 { get { return (byte)(m_Counter >> 8); } }
public byte Key1 { get { return (byte)(m_Counter & 0xFF); } }
public void Increment() { Interlocked.Increment(ref m_Counter); }
   }
}

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...