2015-03-02 54 views
1

我用下面的代碼編寫的AES密鑰和IV與加密文件++:crypto ++中的PumpMessages,讀取密鑰文件?

// write the key: 
SecByteBlock key(AES::DEFAULT_KEYLENGTH); 
SecByteBlock iv(AES::BLOCKSIZE); 

string file = m_file_name + ".key"; 
FileSink* key_out = new FileSink(file.c_str()); 
Base64Encoder base64_key_enc(key_out); 

base64_key_enc.Put(key.BytePtr(), key.size()); 
base64_key_enc.MessageEnd(); 
base64_key_enc.Put(iv.BytePtr(), iv.size()); 
base64_key_enc.MessageEnd(); 

,並讀取該文件中的密鑰和IV後,我使用下列內容:

// read key 
string file = m_file_name + ".key"; 
SecByteBlock key(AES::DEFAULT_KEYLENGTH); 
ArraySink* arr_key_in = new ArraySink(key, key.size()); 
Base64Decoder* base64_key_dec = new Base64Decoder(arr_key_in); 
FileSource source(file.c_str(), false, base64_key_dec); 
source.PumpMessages(1); // read only the key 

// read iv 
SecByteBlock iv(AES::BLOCKSIZE); 
ArraySink* arr_iv_in = new ArraySink(iv, iv.size()); 
base64_key_dec->Detach(arr_iv_in); 
source.PumpAll(); // read the rest (the iv) 

問題是,在閱讀文件後,鍵是正確的,但是iv不是,所以我很厭煩我的sintax可能會出現什麼問題?

密鑰文件的內容十六進制BASE64編碼,它看起來像這樣:

2Gnh3TbAJeQPmza9FKdqNg == FowuKut3pBl7g0Or + 4FJUg ==

==意味着消息的結束/鍵... 首先是關鍵,而另一個是iv,上面的代碼沒有正確地從文件中讀取iv。

我的代碼有什麼問題?

回答

1

問題是,在讀取一個文件後,鍵是正確的,但是iv不是,所以我想知道我的語法有什麼問題?

我覺得問題是圖書館不理解你的消息的概念,所以它不知道如何流信息。我懷疑它一口氣讀完了所有東西。

可能能夠使用source.Pump(AES::DEFAULT_KEYLENGTH * 4/3)進行更正。我認爲這是正確的,以補償基本編碼擴展。或者,您可以讀取Base64連接字符串,在空間上拆分,然後分別處理這兩個消息。

或者您可以嘗試以下操作。它與你的沒什麼不同,只是它寫了一個長度前綴,因此Key和IV可以很容易地被描述和恢復。

一個典型的運行是這樣的:

$ ./cryptopp-test.exe 
Key 1: 434477042E70083441961B2F98A9FB1C 
IV 1: 73A06DA15676B5AFB80C1741B3651982 
Encoded: ABBDRHcELnAINEGWGy+YqfscABBzoG2hVna1r7gMF0GzZRmC 
Key 2: 434477042E70083441961B2F98A9FB1C 
IV 2: 73A06DA15676B5AFB80C1741B3651982 

HexEncoder hex; 
string filename = "test.txt", r1, r2, r3, r4, r5; 

Base64Encoder encoder; 
AlgorithmParameters params = MakeParameters(Pad(), false)(InsertLineBreaks(), false); 
encoder.Initialize(params); 

SecByteBlock k1(AES::DEFAULT_KEYLENGTH), v1(AES::BLOCKSIZE); 

// Generate random key and iv 
OS_GenerateRandomBlock(false, k1, k1.size()); 
OS_GenerateRandomBlock(false, v1, v1.size()); 

// Print key 
hex.Detach(new StringSink(r1)); 
hex.Put(k1, k1.size()); 
hex.MessageEnd(); 

cout << "Key 1: " << r1 << endl; 

// Print iv 
hex.Detach(new StringSink(r2)); 
hex.Put(v1, v1.size()); 
hex.MessageEnd(); 

cout << "IV 1: " << r2 << endl; 

// Write key 
encoder.PutWord16(static_cast<word16>(k1.size()), BIG_ENDIAN_ORDER); 
encoder.Put(k1.data(), k1.size()); 

// Write iv 
encoder.PutWord16(static_cast<word16>(v1.size()), BIG_ENDIAN_ORDER); 
encoder.Put(v1.data(), v1.size()); 
encoder.MessageEnd(); 

// Save it 
FileSink f1(filename.c_str(), true); 
encoder.CopyTo(f1); 
f1.MessageEnd(); 

// Print Base64 encoded 
StringSink ss(r3); 
encoder.TransferTo(ss); 
ss.MessageEnd(); 

cout << "Encoded: " << r3 << endl; 

// Read file 
ByteQueue queue; 
FileSource f2(filename.c_str(), false, new Base64Decoder(new Redirector(queue))); 
f2.PumpAll(); 

// Read key and iv 
SecByteBlock k2, v2; 
word16 size = 0; 

// Read key 
queue.GetWord16(size, BIG_ENDIAN_ORDER); 
k2.resize(size); 
queue.Get(k2, k2.size()); 

// Read iv 
queue.GetWord16(size, BIG_ENDIAN_ORDER); 
v2.resize(size); 
queue.Get(v2, v2.size()); 

// Print key 
hex.Detach(new StringSink(r4)); 
hex.Put(k2, k2.size()); 
hex.MessageEnd(); 

cout << "Key 2: " << r4 << endl; 

// Print iv 
hex.Detach(new StringSink(r5)); 
hex.Put(v2, v2.size()); 
hex.MessageEnd(); 

cout << "IV 2: " << r5 << endl; 

MakeParameters特技基準,以除去填充和換行是在NameValuePairs對加密++維基。

關於OS_GenerateRandomBlock的參考文獻位於Crypto ++ wiki上的RandomNumberGenerator

你可以在Crypto ++ wiki上找到HexEncoder,Base64Encoder,Redirector和朋友。


此外,AES::DEFAULT_KEYLENGTH是16個字節(AES-128)。對於大多數人的需求來說,這通常是足夠的。如果需要(AES-256),你可以將其提升到32。

+0

您的代碼示例發現新的有用的東西,我一定會在下一個學了一大堆,而namevaluepairs中的事情絕對是base64Encoder必須讀你發佈的鏈接後,很明顯,我也misunderstod什麼是加密「郵件」 ++,所以也謝謝你!非常好的答案! – codekiddy 2015-03-03 03:44:04

+1

是的,圖書館有很多。它有助於通過簡化的代碼獲得足部保持狀態。如果您需要網絡安全/ URL安全字母表,還有[Base64URLEncoder](http://www.cryptopp.com/wiki/Base64URLEncoder)。 – jww 2015-03-03 04:07:46

相關問題