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?
Vous m'avez sauvé la vie! – Andiana
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
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