Неверное заполнение блока при попытке расшифровать 2-клавишный тройной DES

Я пытаюсь реализовать 2-ключ тройной DES с crypto ++ в C ++.

Моя реализация основана на коде в вики crypto ++, расположенном Вот.

Код в вики собирается правильно; Я вижу, что он правильно шифрует и расшифровывает, когда я запускаю пример программы.

Для моей реализации я пытаюсь сделать следующее:

  1. пользователь может запустить «desimp.exe encrypt test.txt». Программа зашифрует test.txt, а затем выведет зашифрованный файл с именем test.txt.des. Кажется, это работает правильно.

  2. пользователь может запустить «desimp.exe decrypt test.txt.des», и программа расшифрует test.txt.des и выведет расшифрованный текст в файл «decrypted.txt». Я не могу заставить это работать. Ошибка, которую я получаю:StreamTransformationFilter: найден неправильный отступ блока PKCS # 7«

Я полагаю, что мне может понадобиться сохранить данные из iv в файл во время шифрования. Это правильно? Я попытался сделать это, и я думаю, что я могу правильно сохранить IV в файл — но я думаю, что для чтения в IV, который будет использоваться для расшифровки, он должен быть прочитан как массив 8 байт. Размер файла test.txt.iv при попытке сохранить iv составляет 21 байт. Если это правильный подход, я не уверен, как поступить. Если это неправильный подход, я хотел бы знать, что мне нужно делать по-другому. Вот код:

#ifndef CRYPTOPP_DLL_ONLY
#define CRYPTOPP_DEFAULT_NO_DLL
#endif

#include "dll.h"#include "rc6.h"#include <stdio.h>
#include <string.h>
#include <fstream>
#include <stdlib.h>
#include <string>
#include <streambuf>

USING_NAMESPACE(CryptoPP)
USING_NAMESPACE(std)

#ifdef CRYPTOPP_IMPORTS
static PNew s_pNew = NULL;
static PDelete s_pDelete = NULL;
#endif
#ifdef CRYPTOPP_DLL_ONLY

int __cdecl main(int argc, char *argv[])
{

AutoSeededRandomPool prng;
SecByteBlock key(DES_EDE2::DEFAULT_KEYLENGTH);
prng.GenerateBlock(key, key.size());
byte iv[DES_EDE2::BLOCKSIZE];
prng.GenerateBlock(iv, sizeof(iv));
string plain = "CBC Mode Test";
string cipher, encoded, recovered;char *fileName = argv[1];
char *runMode = argv[2];
char *ivFile = argv[3];

cout << "ARGUMENT 1: " << fileName << endl;
cout << "ARGUMENT 2: " << runMode << endl;

string fileNameString(fileName);
string encryptedFileNameString = fileNameString + ".des";//add .des to the filename of the encrypted file once it's generated
string ivString = fileNameString + ".iv";//iv file
string runModeString(runMode);

if (runModeString == "encrypt")
{
ifstream t(fileName);
string str((std::istreambuf_iterator<char>(t)),
istreambuf_iterator<char>());
try
{
cout << "plain text: " << str << endl;

CBC_Mode< DES_EDE2 >::Encryption e;
e.SetKeyWithIV(key, key.size(), iv);

// The StreamTransformationFilter adds padding
//  as required. ECB and CBC Mode must be padded
//  to the block size of the cipher.
StringSource ss1(str, true,
new StreamTransformationFilter(e,
new StringSink(cipher)
) // StreamTransformationFilter
); // StringSource
}
catch(const CryptoPP::Exception& e)
{
cerr << e.what() << endl;
exit(1);
}
// Pretty print
StringSource ss2(cipher, true,
new HexEncoder(
new StringSink(encoded)
) // HexEncoder
); // StringSource

cout << "cipher text: " << encoded << endl;//"encoded" is just the pretty print version of the ciphertext.
ofstream fout(encryptedFileNameString);
fout << cipher;
fout.close();//outputs/saves the encrypted file
cout << "Encrypted file was saved to local path as " << encryptedFileNameString << endl;

ofstream fout2(ivString);
fout2 << iv;
fout2.close();
cout << "iv was saved to local path as " << ivString << endl;
}

if (runModeString == "decrypt")// USER WANTS TO DECRYPT A FILE
{
ifstream t2(fileName);
string str2((istreambuf_iterator<char>(t2)),istreambuf_iterator<char>());
cipher = str2;

try
{
CBC_Mode< DES_EDE2 >::Decryption d;
d.SetKeyWithIV(key, key.size(), iv);
// The StreamTransformationFilter removes
//  padding as required.
StringSource ss3(cipher, true,
new StreamTransformationFilter(d,
new StringSink(recovered)
) // StreamTransformationFilter
); // StringSource

cout << "recovered text: " << recovered << endl;
}
catch(const CryptoPP::Exception& e)
{
cerr << e.what() << endl;
exit(1);
}
}
return 0;
}//end main

extern "C" __declspec(dllexport) void __cdecl SetNewAndDeleteFromCryptoPP(PNew pNew, PDelete pDelete, PSetNewHandler pSetNewHandler)
{
s_pNew = pNew;
s_pDelete = pDelete;
}

void * __cdecl operator new (size_t size)
{
return s_pNew(size);
}

void __cdecl operator delete (void * p)
{
s_pDelete(p);
}

#endif

1

Решение

Я думаю, что вам нужно открыть ваш зашифрованный файл с std::ios_base::binary в режиме (как для чтения, так и для записи); в противном случае библиотека ввода / вывода будет искажать последовательности, которые выглядят как концы строк.

1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]