2015-09-11 4 views
1

Ok donc j'ai 5 fichiers que je crypte. Je ne mets pas le IV.Fichiers ne décryptant pas complètement, mode AES CBC. Premier bloc non décrypté. WCAPI

va bien du fichier poing Décrypter,

alors le premier bloc des fichiers restants ne sont pas déchiffrées. Par conséquent, les fichiers décryptent 99%. J'ai essayé de régler l'IV sur une valeur statique et une valeur aléatoire, même résultat.

Le premier fichier que je crypte NE DOIT PAS être le premier fichier que je décrypte pour qu'il soit décrypté à 100%.

Ce qui me porte à croire qu'il a à voir avec le décryptage? Donc, pour le cryptage, j'importe une clé aes pour créer un handle de clé.

alors je crypter un fichier et de passer à un autre fichier en utilisant la même poignée clé ...

Dois-je avoir une nouvelle poignée clé pour chaque fichier ..?

Y a-t-il une fonction pour effacer la poignée de la clé? Quelque chose me dit que WCAPI utilise le dernier bloc du dernier fichier comme IV pour le prochain fichier? Excusez-moi si je peux mal comprendre quelque chose.

Voici la fonction decrypt_file:

DWORD dwMode = CRYPT_MODE_CBC; 

LPVOID aes_key = NULL; 
LPVOID tmp_blk_buff = NULL; 
DWORD bytes_read = NULL; 

BOOL eof = FALSE; 

DWORD tmp_blk_buff_size = TMP_BLOCK_BUFFER_SIZE(context->in_size); 

tmp_blk_buff = VirtualAlloc(0, tmp_blk_buff_size, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); 

Utils::zero_mem(tmp_blk_buff, tmp_blk_buff_size); 

LPVOID iv_ = NULL; 
iv_ = VirtualAlloc(0, AES_BLOCK_SIZE_, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); 
Utils::zero_mem(iv_, AES_BLOCK_SIZE_); 

/*BYTE iv[AES_BLOCK_SIZE_] = { 
    0xAD, 0xAD, 0xAD, 0xAD, 
    0xAD, 0xAD, 0xAD, 0xAD, 
    0xAD, 0xAD, 0xAD, 0xAD, 
    0xAD, 0xAD, 0xAD, 0xAD 
}; 
*/ 
// Utils::copy_mem(iv_, AES_BLOCK_SIZE_, iv, AES_BLOCK_SIZE_); 


//CryptSetKeyParam(context->aes_hKey, KP_IV, (BYTE*)&iv_, 0); 

CryptSetKeyParam(context->aes_hKey, KP_MODE, (BYTE*)&dwMode, 0); 

// Encrypt data 
do{ 
    Utils::zero_mem(tmp_blk_buff, tmp_blk_buff_size); 
    bytes_read = NULL; 

    ReadFile(hFile_in, tmp_blk_buff, AES_BLOCK_SIZE_, &bytes_read, NULL); 

    if (bytes_read < AES_BLOCK_SIZE_) 
    { 
     eof = TRUE; 
    } 

    if (!CryptDecrypt(context->aes_hKey, NULL, eof, 0,(LPBYTE)tmp_blk_buff, &bytes_read)) 
    { 
     context->last_error = GetLastError(); 

     eof = TRUE; 
    } 

    WriteFile(hFile_out, tmp_blk_buff, bytes_read, &bytes_read, NULL); 

} while (!eof); 

// =============== 
// Zero and Free Allocated memory. 
Utils::zero_mem(tmp_blk_buff, tmp_blk_buff_size); 
VirtualFree(tmp_blk_buff, tmp_blk_buff_size, MEM_RELEASE); 

return (DWORD)1; 
+0

Je pense que vous avez raison d'apporter le dernier bloc d'un fichier à la première de la suivante. Si vous ne définissez pas l'IV de toute façon, vous pouvez également spécifier le mode ECB, en gardant à l'esprit que la BCE n'est pas très sûre. Sinon, si vous voulez rester en mode CBC, réinitialisez l'IV à tous les 0 octets avant de déchiffrer chaque nouveau fichier. – WDS

+0

Mais juste pour clarifier, CBC avec un IV de tous les 0 octets est exactement le même que BCE. Mais cela ne s'appliquerait qu'au premier bloc du fichier. Après cela, au fur et à mesure que le chaînage commence, le mode CBC protégerait les autres blocs. – WDS

+0

@WDS Je pense que vous savez ce que vous voulez dire, mais votre déclaration est trompeuse. Pour clarifier, CBC avec un IV de tous les 0 et de la BCE ne sont pas la même chose. Le résultat du premier bloc est le même, mais les blocs suivants sont calculés différemment entre les deux. Voir https://en.wikipedia.org/wiki/Block_cipher_mode_of_operation pour une photo de la BCE et de CBC. –

Répondre

0

J'ai utilisé CryptDuplicateKey avec un appel approprié à DestroyKey, qui a résolu mes problèmes.

Utilisation de la touche dupliquée pour définir les paramètres, en maintenant la touche originale non touchée.

0

Oui, cela suggère que vous avez le IV différent sur une paire Crypter/décrypter donné.

La raison pour laquelle seul le premier bloc est «corrompu» est que les erreurs de bloc CBC se propagent uniquement au bloc suivant (et pas plus loin).

Vous enchaînez à partir d'une opération précédente (si vous réutilisez le contexte sur plusieurs fichiers) ou vous n'initialisez pas le contexte à la même valeur pour le chiffrement et le déchiffrement.

En regardant votre code, vous avez commenté CryptSetKeyParam(....,KP_IV,....), ce qui signifie que votre contexte AES a probablement des données inconnues dans la IV.

Une pratique relativement courante est toujours d'utiliser des 0 pour l'IV, mais de mettre un bloc de "sel" aléatoire au début des données. Vous ignorez alors le premier bloc de données lorsque vous décryptez. C'est seulement là pour randomiser les données. OU, vous pouvez randomiser la IV, mais l'envoyer en préfixe en texte brut au message crypté. C'est aussi très commun.

Ou vous pouvez randomiser le IV sur crypter, mettre dans un bloc de données aléatoires avant le message réel. Utilisez n'importe quel IV sur le décryptage et jetez ce premier bloc (parce que ce sera la poubelle).C'est à peu près le même résultat (vous finissez par transmettre 16 octets en overhead), mais vous devriez mettre un peu de hasard dans votre message (soit via le IV ou le premier bloc) pour contrecarrer les attaques de raccourci.