为了使用Crypto ++加密大文件,我使用类似Java的Init-Update-Final in Crypto++跟踪ecrypting,
演示代码似乎有效,每次调用Put时,输出字节都会打印到屏幕上:
encoder.Put(buffer, ready);
但我无论如何都找不到所有密文的输出。例如
'H' -> print 01 to screen
'E' -> print A9 to screen
'L' -> print 5J to screen
'L' -> print 13 to screen
'O' -> print 3d to screen ...
但我无法将完整结果检索到字节数组 01A95J133d ...
问题in here与使用Init-Update-Final加密大型文件有关,但似乎还没有提供有效的解决方案。
这是完整的演示代码:
enum { ENCRYPT_MODE = 1, DECRYPT_MODE = 2 };
struct JavaAlgorithmParameter
{
JavaAlgorithmParameter()
: key(NULL), ksize(0), iv(NULL), vsize(0) {}
const byte* key;
size_t ksize;
const byte* iv;
size_t vsize;
};
/////////////////////////
/////////////////////////
class JavaCipher
{
public:
static JavaCipher* getInstance(const std::string& transformation);
void init(int opmode, const JavaAlgorithmParameter& params);
size_t update(const byte* in, size_t isize, byte* out, size_t osize);
size_t final(byte* out, size_t osize);
std::string getAlgorithm() const;
protected:
JavaCipher(const std::string& transformation);
private:
std::string m_transformation;
member_ptr<SymmetricCipher> m_cipher;
member_ptr<StreamTransformationFilter> m_filter;
};
/////////////////////////
/////////////////////////
JavaCipher* JavaCipher::getInstance(const std::string& transformation)
{
return new JavaCipher(transformation);
}
JavaCipher::JavaCipher(const std::string& transformation)
: m_transformation(transformation) { }
std::string JavaCipher::getAlgorithm() const
{
return m_transformation;
}
/////////////////////////
/////////////////////////
size_t JavaCipher::final(byte* out, size_t osize)
{
m_filter.get()->MessageEnd();
if (!out || !osize || !m_filter.get()->AnyRetrievable())
return 0;
size_t t = CryptoPP::STDMIN(m_filter.get()->MaxRetrievable(), (word64)osize);
t = m_filter.get()->Get(out, t);
return t;
}
/////////////////////////
/////////////////////////
size_t JavaCipher::update(const byte* in, size_t isize, byte* out, size_t osize)
{
if (in && isize)
m_filter.get()->Put(in, isize);
if (!out || !osize || !m_filter.get()->AnyRetrievable())
return 0;
size_t t = STDMIN(m_filter.get()->MaxRetrievable(), (word64)osize);
t = m_filter.get()->Get(out, t);
return t;
}
/////////////////////////
/////////////////////////
void JavaCipher::init(int opmode, const JavaAlgorithmParameter& params)
{
if (m_transformation == "AES/ECB/PKCSPadding" && opmode == ENCRYPT_MODE)
{
m_cipher.reset(new ECB_Mode<AES>::Encryption);
m_cipher.get()->SetKey(params.key, params.ksize);
m_filter.reset(new StreamTransformationFilter(*m_cipher.get(), NULL, BlockPaddingSchemeDef::PKCS_PADDING));
}
else if (m_transformation == "AES/ECB/PKCSPadding" && opmode == DECRYPT_MODE)
{
m_cipher.reset(new ECB_Mode<AES>::Decryption);
m_cipher.get()->SetKey(params.key, params.ksize);
m_filter.reset(new StreamTransformationFilter(*m_cipher.get(), NULL, BlockPaddingSchemeDef::PKCS_PADDING));
}
else if (m_transformation == "AES/CBC/PKCSPadding" && opmode == ENCRYPT_MODE)
{
m_cipher.reset(new CBC_Mode<AES>::Encryption);
m_cipher.get()->SetKeyWithIV(params.key, params.ksize, params.iv);
m_filter.reset(new StreamTransformationFilter(*m_cipher.get(), NULL, BlockPaddingSchemeDef::PKCS_PADDING));
}
else if (m_transformation == "AES/CBC/PKCSPadding" && opmode == DECRYPT_MODE)
{
m_cipher.reset(new CBC_Mode<AES>::Decryption);
m_cipher.get()->SetKeyWithIV(params.key, params.ksize, params.iv);
m_filter.reset(new StreamTransformationFilter(*m_cipher.get(), NULL, BlockPaddingSchemeDef::PKCS_PADDING));
}
else if (m_transformation == "AES/CTR/NoPadding" && opmode == ENCRYPT_MODE)
{
m_cipher.reset(new CTR_Mode<AES>::Encryption);
m_cipher.get()->SetKeyWithIV(params.key, params.ksize, params.iv);
m_filter.reset(new StreamTransformationFilter(*m_cipher.get(), NULL, BlockPaddingSchemeDef::NO_PADDING));
}
else if (m_transformation == "AES/CTR/NoPadding" && opmode == DECRYPT_MODE)
{
m_cipher.reset(new CTR_Mode<AES>::Decryption);
m_cipher.get()->SetKeyWithIV(params.key, params.ksize, params.iv);
m_filter.reset(new StreamTransformationFilter(*m_cipher.get(), NULL, BlockPaddingSchemeDef::NO_PADDING));
}
else
throw NotImplemented(m_transformation + " is not implemented");
}
/////////////////////////
/////////////////////////
int main(int argc, char* argv[])
{
try
{
byte key[32], iv[16];
OS_GenerateRandomBlock(false, key, COUNTOF(key));
OS_GenerateRandomBlock(false, iv, COUNTOF(iv));
HexEncoder encoder(new FileSink(cout));
JavaAlgorithmParameter params;
params.key = key;
params.ksize = COUNTOF(key);
params.iv = iv;
params.vsize = COUNTOF(iv);
//JavaCipher* cipher = JavaCipher::getInstance("AES/CTR/NoPadding");
JavaCipher* cipher = JavaCipher::getInstance("AES/CBC/PKCSPadding");
cipher->init(ENCRYPT_MODE, params);
cout << "Algorithm: " << cipher->getAlgorithm() << endl;
cout << "Key: ";
encoder.Put(key, COUNTOF(key));
cout << endl;
cout << "IV: ";
encoder.Put(iv, COUNTOF(iv));
cout << endl;
char * allText = FileUtil::readAllByte("1MB.txt");
long len = strlen(allText);
byte buffer[64];
size_t ready = 0;
for (unsigned int i = 0; i <= len; i++)
{
byte b = allText[i];
//cout << "Put 0x";
encoder.Put(b);
cout << endl;
ready = cipher->update(&b, 1, buffer, COUNTOF(buffer));
if (ready)
{
//cout << "Get: ";
encoder.Put(buffer, ready);
cout << endl;
}
}
ready = cipher->final(NULL, 0);
if (ready)
{
//cout << "Final: ";
encoder.Put(buffer, ready);
cout << endl;
}
ready = cipher->final(buffer, COUNTOF(buffer));
if (ready)
{
//cout << "Final: ";
encoder.Put(buffer, ready);
cout << endl;
}
delete cipher;
getchar();
}
catch (const Exception& ex)
{
cerr << ex.what() << endl;
}
return 0;
}
答案 0 :(得分:1)
但无论如何我无法找到所有密文的输出。对于 示例
cipher::update
但我无法将完整结果检索到字节数组01A95J133d ...
在没有输出缓冲区的情况下调用cipher->update(&b, 1, NULL, 0);
:
cipher::final
然后,在调用size_t size = <some appropriately size for the cipher text>;
byte result[size];
cipher->final(result, size);
:
<some appropriately size for the cipher text>
如果您遇到size_t ready() const
{
return m_filter.get()->MaxRetrievable();
}
问题,请在课程中添加新方法:
{{1}}