2009-04-01 5 views
1

Je suis en train de traduire un client TCP C++ en C#. Le client est utilisé pour encoder 4 octets d'un tableau en utilisant blowfish.C#: Blowfish Chiffrer un seul mot

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); 

Dans le code C++, lorsque la ligne "Blowfish.Encode" est appelée avec ces paramètres, il va dans la fonction 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; 
} 

Pour être clair, la boucle n'est exécutée qu'une seule fois en raison de la courte longueur des octets passés (4).

Un seul appel est exécuté à partir de ce grand code (une seule fois), l'appel est:

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

// qui signifie que le code passe les deux premières déclarations et se laisse alors la boucle et la fonction.

De mon point de vue, la solution est cachée quelque part dans la fonction encipher:

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; 
} 

Les définitions:

#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]) 

Le problème est que la fonction Blowfish_Encipher en C++ a deux paramètres: Entrée (xl) en tant que dword et sortie (xr) en tant que dword.

La fonction C# Blowfish Encrypt_Block a quatre paramètres, pourquoi?

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

Contrairement au C++ Blowfish, EncryptBlock appels Crypter à la place Chiffrer appeler EncryptBlock.Maybe EncryptBlock est pas le C++ Blowfish_Encipher? De toute façon, mon problème est que lorsque j'appelle le code C++ avec ce tableau de 6 octets demandant au blowfish de ne coder que les 4 derniers octets, il le fait. Alors que si j'appelle la fonction de chiffrement en C# avec ces 4 octets, elle renvoie 0x00 (si vous souhaitez voir le C# Blowfish, vérifiez mes premières lignes - j'ai ajouté un hyperlien ici).

Remarque Je ne peux pas modifier la structure du paquet, elle devrait être exactement comme cela, mais cryptée.

J'ai aussi essayé ceci:

Connaître les fonctions C++ Encrpypt exécute un seul appel - Blowfish Encipher.I a essayé d'appeler EncryptBlock en C# directement, mais il y a aussi les entrées et sorties Salut Uint32 et Low Uint32, comment les répartir en HI ou LO? Cela fonctionnera-t-il si Encrypt_Block appelle blowfish Crypter en C#? Je ne suis pas très sûr.

Merci d'avance!

+0

Duplicata de http://stackoverflow.com/questions/704402/c-blowfish-works-with-fewer-letters-but-c-blowfish-doesnt et http://stackoverflow.com/questions/703351/c -blowfish-doesnt-work-with-moins-lettres –

+0

Je ne peux pas les cogner, je n'ai pas effacé certaines choses dans mes questions précédentes comme "Note je ne peux pas changer la structure du paquet, ça devrait être juste comme ça, mais chiffré. ". Il y a des réponses, que j'ai commentées, mais aucune des personnes qui les a écrites n'est assez intéressée pour répondre à mes commentaires. –

+0

Hmmm ... qu'en est-il de cette soudaine augmentation de presque deux fois des questions sur le cryptage de Blowfish? – Noldorin

Répondre

1

Blowfish fonctionne sur des blocs de huit octets.La seule façon de chiffrer des données qui ne dépassent pas huit octets (ou un multiple de huit) consiste à les masquer (dans ce cas, avec des zéros).

Vous devez transmettre un tampon de huit octets dans votre fonction C++, puisque vous cryptez en place. Le code que vous avez posté cryptera réellement quatre octets supplémentaires de mémoire adjacente ((DWORD *)(pInput + 4)), ce qui n'est évidemment pas ce que vous voulez. En outre, les huit octets de sortie sont nécessaires pour décrypter - donc, malheureusement, vous ne pouvez pas simplement passer quatre des octets cryptés et s'attendre à ce qu'ils soient décryptés avec succès à l'autre extrémité.

Je sais que cela ne résoudra pas votre problème - je ne vois aucun moyen de le résoudre, puisque vous voulez envoyer seulement quatre octets de données cryptées et Blowfish produit toujours un minimum de huit!

Questions connexes