2009-04-01 3 views
1

Я переводил C++ TCP Client в C#. Клиент используется для кодирования 4 байтов массива с помощью blowfish.C#: Blowfish Шифровать один dword

C++ Blowfish

C# Blowfish(C# NET)

C++

BYTE response[6] = 
    { 
     0x00, 0x80, 0x01, 0x61, 0xF8, 0x17 
    }; 

    // Encrypt the last 4 bytes of the packet only(0x01,0x061,0xF8,0x17) 
    blowfish.Encode(responce + 2, responce + 2, 4); 

    // Send the packet 
    send(s, (char*)sendPtr, sendSize, 0); 

C#

responce = new byte[6] { 0x00, 0x80, 0x01, 0x61, 0xF8, 0x17}; 

    // Encrypt the last 4 bytes of the packet only(0x01,0x061,0xF8,0x17) 
    Handshake.blowfish.Encrypt(responce, 2, responce, 2, 4); 

    // Send the packet 
    WS.sock.Send(encrypted); 

В коде C++, когда линия "Blowfish.Encode" вызывается с этими параметрами, это переходит в функцию cBlowfish.Encrypt

DWORD cBlowFish::Encode(BYTE * pInput, BYTE * pOutput, DWORD lSize) 
{ 
DWORD lCount, lOutSize, lGoodBytes; 
BYTE *pi, *po; 
int  i, j; 
int  SameDest =(pInput == pOutput ? 1 : 0); 

lOutSize = GetOutputLength(lSize); 
for(lCount = 0; lCount < lOutSize; lCount += 8) 
{ 
    if(SameDest) // if encoded data is being written into input buffer 
    { 
     if(lCount < lSize - 7) // if not dealing with uneven bytes at end 
     { 
      Blowfish_encipher((DWORD *) pInput, (DWORD *)(pInput + 4)); 
     } 
     else  // pad end of data with null bytes to complete encryption 
     { 
      po = pInput + lSize; // point at byte past the end of actual data 
      j =(int)(lOutSize - lSize); // number of bytes to set to null 
      for(i = 0; i < j; i++) 
       *po++ = 0; 
      Blowfish_encipher((DWORD *) pInput, (DWORD *)(pInput + 4)); 
     } 
     pInput += 8; 
    } 
    else   // output buffer not equal to input buffer, so must copy 
    {    // input to output buffer prior to encrypting 
     if(lCount < lSize - 7) // if not dealing with uneven bytes at end 
     { 
      pi = pInput; 
      po = pOutput; 
      for(i = 0; i < 8; i++) 
       // copy bytes to output 
       *po++ = *pi++; 
      // now encrypt them 
      Blowfish_encipher((DWORD *) pOutput, (DWORD *)(pOutput + 4)); 
     } 
     else  // pad end of data with null bytes to complete encryption 
     { 
      lGoodBytes = lSize - lCount; // number of remaining data bytes 
      po = pOutput; 
      for(i = 0; i <(int) lGoodBytes; i++) 
       *po++ = *pInput++; 
      for(j = i; j < 8; j++) 
       *po++ = 0; 
      Blowfish_encipher((DWORD *) pOutput, (DWORD *)(pOutput + 4)); 
     } 
     pInput += 8; 
     pOutput += 8; 
    } 
} 
return lOutSize; 
} 

Для того, чтобы это стало ясно, цикл выполняется только один раз из-за короткой длины пройденных байтов (4).

только один вызов выполняется из этого огромного кода (только один раз), вызов:

Blowfish_encipher((DWORD *) pInput, (DWORD *)(pInput + 4)); 

// означает код прохождения первых два, если заявления, а затем выходит из цикла и функции.

С моей точки зрения, решение скрывается где-то внутри функции шифровки:

void cBlowFish::Blowfish_encipher(DWORD *xl, DWORD *xr) 
{ 
union aword Xl, Xr; 

Xl.dword = *xl; 
Xr.dword = *xr; 

Xl.dword ^= PArray [0]; 
ROUND(Xr, Xl, 1); 
ROUND(Xl, Xr, 2); 
ROUND(Xr, Xl, 3); 
ROUND(Xl, Xr, 4); 
ROUND(Xr, Xl, 5); 
ROUND(Xl, Xr, 6); 
ROUND(Xr, Xl, 7); 
ROUND(Xl, Xr, 8); 
ROUND(Xr, Xl, 9); 
ROUND(Xl, Xr, 10); 
ROUND(Xr, Xl, 11); 
ROUND(Xl, Xr, 12); 
ROUND(Xr, Xl, 13); 
ROUND(Xl, Xr, 14); 
ROUND(Xr, Xl, 15); 
ROUND(Xl, Xr, 16); 
Xr.dword ^= PArray [17]; 

*xr = Xl.dword; 
*xl = Xr.dword; 
} 

Определения:

#define S(x,i)   (SBoxes[i][x.w.byte##i]) 
#define bf_F(x)   (((S(x,0) + S(x,1))^S(x,2)) + S(x,3)) 
#define ROUND(a,b,n) (a.dword ^= bf_F(b)^PArray[n]) 

Проблема заключается в том, что функция Blowfish_Encipher в C++ имеет два параметра: Введите (xl) как dword и Output (xr) как dword.

Функция C# Blowfish Encrypt_Block имеет четыре параметра, почему?

 public void EncryptBlock(uint hi,uint lo,out uint outHi,out uint outLo) 

В отличие от Blowfish C++, EncryptBlock вызовы Encrypt вместо шифрования позвонить EncryptBlock.Maybe EncryptBlock НЕ С ++ Blowfish_Encipher?

Во всяком случае, моя проблема в том, что когда я вызываю код C++ с этим массивом из 6 байтов, запрашивая укол, чтобы кодировать только последние 4 байта, он делает это.

Хотя если я вызываю функцию шифрования в C# с этими 4 байтами, она возвращает 0x00. (Если вы хотите увидеть C# Blowfish, проверьте мои первые строки - я добавил туда гиперссылку).

Примечание. Я не могу изменить структуру пакета, он должен быть таким же, но зашифрованным.

Я также попытался это:

Зная функции C++ Encrpypt выполняет только один вызов - Blowfish Encipher.I пытался вызвать EncryptBlock в C# непосредственно, но есть Привет uint32 и Low UInt32 как вход и выход, то как в распространить их на HI или LO? Будет ли это работать, если Encrypt_Block вызывает blowfish Encrypt в C#? Я совершенно не уверен.

Спасибо заранее!

+0

Дубликат http://stackoverflow.com/questions/704402/c-blowfish-works-with-fewer-letters-but-c-blowfish-doesnt и http://stackoverflow.com/questions/703351/c -blowfish-doesnt-work-with-less-letters –

+0

Я не могу их поднять, я не заметил некоторых вещей в моих предыдущих вопросах, таких как «Заметьте, я не могу изменить структуру пакета, это должно быть так, но зашифрованы ». Есть ответы, которые я прокомментировал, но ни один из тех, кто их написал, не заинтересован, чтобы ответить на мои комментарии. –

+0

Хммм ... что с этим внезапным всплеском почти точно повторяющихся вопросов о шифровании Blowfish? – Noldorin

ответ

1

Blowfish работает на восьми блоков байтов.Единственный способ зашифровать данные, которые не хватает восьми байтов (или нескольких из восьми), - это выгрузить его (в этом случае с нулями).

Вам необходимо передать восьмибайтовый буфер в вашу C++-функцию, поскольку вы шифруете на месте. Код, который вы отправили, фактически зашифрует четыре дополнительных байта смежной памяти ((DWORD *)(pInput + 4)), что явно не то, что вы хотите. Кроме того, для дешифрования требуются все восемь выходных байтов - поэтому, к сожалению, вы не можете просто передать четыре зашифрованных байта и ожидать, что они будут дешифрованы успешно на другом конце.

Я знаю, что это не решает вашу проблему - я не вижу способа решить эту проблему, так как вы хотите отправить только четыре байта зашифрованных данных, а Blowfish всегда производит минимум восемь!

Смежные вопросы