我想在C++中使用crypto ++實現2鍵三重DES。試圖解密2鍵三元組的無效塊填充DES
我的實現基於位於here的crypto ++ wiki中的代碼。
維基上的代碼正確構建;當我運行示例程序時,我可以看到它正在加密和解密。
對於我的實現,我想做到以下幾點:
用戶可以運行 「desimp.exe加密的test.txt」。該程序將加密test.txt,然後輸出一個名爲test.txt.des的加密文件。這似乎工作正常。
用戶可以運行「desimp.exe decrypt test.txt.des」,程序將解密test.txt.des並將解密後的文本輸出到文件「decrypted.txt」我無法獲得此信息工作。我得到的錯誤是「StreamTransformationFilter:無效的PKCS#7塊填充發現」
我認爲我可能需要的數據在四在加密時保存到一個文件中。它是否正確?我試過這樣做,我認爲我能夠將iv保存到一個文件中,但我認爲,爲了讀取要用於解密的iv文件,需要將其作爲數組讀取8個字節。當我嘗試保存iv時,test.txt.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
我最終實現了Botan加密庫,所以我不再需要這個問題的解決方案。 – Krondorian