2016-11-29 2 views
0

J'essaye de faire CTR manuellement en haut du mode ECB (mais toujours) en utilisant Crypto ++. L'idée est:Crypto ++ Outil manuel en mode CTR

Pour seul bloc: Il suffit d'utiliser la BCE pour bloc multiple, utiliser l'algorithme CTR (AFAIK):

//We have n block of plain data -> M 
PlainData M[n]; 
key; 
iv; 
char *CTR; 
cipher =""; 
for(i = 0; i<n; i++){ 
    if(i ==0){ 
     CTR = iv; 
    } 
    ei = encryptECB(CTR + i) 
    cipherI = xor(ei, M[i]) 
    cipher += cipherI; 
} 

// Mon XOR() à deux XOR tableau de caractères

void xor(char *s1, char* s2, char *& result, int len){ 

    try{ 
     int i; 
     for (i = 0; i < len; i++){ 
      int u = s1[i]^s2[i]; 
      result[i] = u; 
     } 
     result[i] = '\0'; 
    } 
    catch (...){ 
     cout << "Errp"; 
    } 
} 

essai 1: 100% Crypto ++ CTR

string auto_ctr(char * s1, long size){ 
    CTR_Mode<AES>::Encryption e; 
    e.SetKeyWithIV(key, sizeof(key), iv, sizeof(iv)); 
    string cipherZ; 
    StringSource s(s1, true, 
     new StreamTransformationFilter(e, 
     new StringSink(cipherZ), BlockPaddingSchemeDef::BlockPaddingScheme::NO_PADDING 
     ) 
     ); 
    return cipherZ; 
} 

Test 2: Manuel CTR basé sur BCE

string encrypt(char* s1, int size){ 
    ECB_Mode<AES>::Encryption e; 
    e.SetKey(key, size); 
    string cipher; 
    string s(s1, size); 
    StringSource ss1(s, true, 
     new StreamTransformationFilter(e, 
     new StringSink(cipher), BlockPaddingSchemeDef::BlockPaddingScheme::NO_PADDING 
     ) // StreamTransformationFilter 
     ); // StringSource 
    return cipher; 
} 

static string manual_ctr(char *plain, long &size){ 
    int nBlocks = size/BLOCK_SIZE; 
    char* encryptBefore = new char[BLOCK_SIZE]; 
    char *ci = new char[BLOCK_SIZE] ; 
    string cipher; 
    for (int i = 0; i < nBlocks; i++){ 
     //If the first loop, CTR = IV 
     if (i == 0){ 
      memcpy(encryptBefore, iv, BLOCK_SIZE); 
     } 
     encryptBefore[BLOCK_SIZE] = '\0'; 
     memcpy(encryptBefore, encryptBefore + i, BLOCK_SIZE); 


     char *buffer = new char[BLOCK_SIZE]; 
     memcpy(buffer, &plain[i], BLOCK_SIZE); 
     buffer[BLOCK_SIZE] = '\0'; 
     //Encrypt the CTR 
     string e1 = encrypt(encryptBefore, BLOCK_SIZE); 
     //Xor it with m[i] => c[i] 
     xor((char*)e1.c_str(), buffer, ci, BLOCK_SIZE); 
     //Append to the summary cipher 
     /*for (int j = 0; j < BLOCK_SIZE/2; j++){ 
      SetChar(cipher, ci[j], i*BLOCK_SIZE + j); 
     }*/ 
     cipher += ci; 
     //Set the cipher back to iv 
     //memcpy(encryptBefore, ci, BLOCK_SIZE); 
    } 
    return cipher; 
} 

Et voici principal pour les essais:

void main(){ 

    long size = 0; 
    char * plain = FileUtil::readAllByte("some1.txt", size); 
    string auto_result = auto_ctr(plain, size); 
    string manual_result = manual_ctr(plain, size); 
    getchar(); 
} 

Le auto_result est:

« YZ + eÞsÂÙ \ bü' \ x1a¨Ü_ÙR • L¸Ð € |å «ÎÍÊ [w®Ÿg \ fT½ \ ý7! p \ r^ÍÇ † 1cZï.s% \ x1ei {ÚMØ ... Pä¾õ \ x46 \ r5 \ tâyï,ú \ x16ç'Qiæ² \ x15š € á^ªê] W ÊNqdŒ ¥ † ¾j% 8.Ìù \ x6Þ> ÔÏ '[c \ x19 "

Le manual_result est:

« yz + eÞsÂÙ \ bü' \ x1a¨Ü_Ù · \ x18ýuù \ n \ nl \ X11A \ X19A † Žaðƒºñ®GäþŽá • \ x11ÇYœf +^Q \ x1a \ x13B³'QQμºëÑÌåM \ "\ x12 \ x115â \ x10¿Ô « > s ° ‰ = \ x18 * \ x1c: ²IF'n @ ŠŠ¾mGÂzõžÀ \ x1eÏ \ SëYU¼í ' » >

Quel est le problèm m avec mon outil?

Répondre

1

Depuis votre premier bloc semble fonctionner très bien, je ne l'ai cherché des problèmes dans la gestion du compteur lui-même et voici ce qui me semble mal:

memcpy (encryptBefore, encryptBefore + i, TAILLE DE BLOC);

Ici, vous essayez d'augmenter votre IV i fois, je suppose, mais ce n'est pas ce qui se passe, ce que vous faites est d'essayer de copier dans votre pointeur encryptBefore le contenu du pointeur encryptBefore+i couvrant plus BLOCK_SIZE octets. Ce n'est pas du tout l'incrémentation de la IV, mais cela fonctionne pour le premier bloc car alors i=0.

Qu'est-ce que vous voulez faire est de créer réellement un grand entier en utilisant CryptoPP::Integer à utiliser comme IV et incrément entier, puis le convertir en un tableau d'octets en utilisant le lorsque vous avez besoin d'utiliser des octets à la place fonction Encode(byte *output, size_t outputLen, Signedness sign=UNSIGNED) const de la classe cryptopp Entier des entiers.

Ps: lors de l'exécution des opérations i/o, je vous recommande d'utiliser des chaînes hexadécimaux, jetez un oeil à la classe CryptoPP::HexEncoder et HexDecoder, ils sont tous deux well documented on CryptoPP wiki.

+0

Vous m'avez sauvé la vie! – Andiana

+0

De rien. S'il vous plaît noter que je ne sais pas comment vous générez votre IV, mais faites très attention de ne jamais utiliser deux fois la même IV, sinon dès que vous crypter deux fois avec la même clé (mais différentes données) vous exposer vos données aux attaques classiques contre le mode CTR. Donc, assurez-vous que vous n'avez pas deux fois la même IV (même après l'incrément). Donc, quand vous utilisez par exemple 17 comme un IV pour chiffrer 5 blocs, vous ne pouvez plus utiliser toute la gamme de IV de 17 à 22! – Lery

+2

Crypto ++ fournit [IncrementCounterByOne] (http://www.cryptopp.com/docs/ref/misc_8h.html) à des fins d'incrémentation d'un compteur représenté sous la forme d'un tableau d'octets. – jww