Я переводил C++ TCP Client в C#. Клиент используется для кодирования 4 байтов массива с помощью blowfish.C#: Blowfish Шифровать один dword
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#? Я совершенно не уверен.
Спасибо заранее!
Дубликат 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 –
Я не могу их поднять, я не заметил некоторых вещей в моих предыдущих вопросах, таких как «Заметьте, я не могу изменить структуру пакета, это должно быть так, но зашифрованы ». Есть ответы, которые я прокомментировал, но ни один из тех, кто их написал, не заинтересован, чтобы ответить на мои комментарии. –
Хммм ... что с этим внезапным всплеском почти точно повторяющихся вопросов о шифровании Blowfish? – Noldorin