原文https://www.cryptopp.com/wiki/User_Guide:_cryptlib.h
Exception
所有的異常類在Crypto++都派生自Exception,Exception僅僅是一個標準c++庫 通過std::exception定義的異常接口.因此它能捕獲下面展示的所有Crypto++異常
原文中的測試代碼在win10無法通過,錯誤處是remove函數,錯誤代碼permission denied, 感覺是windows文件系統權限管理的原因,實驗結果是,只是不創建文件就刪除(remove)
沒問題,但是創建文件後刪除就會失敗,應該和文件句柄有關,應該出門右轉windows核心編程
int main() {
try {
static char* const file_name = "A:\\CryptoPP_Author_Use\\cryptlib\\test_cryplib\\Release\\file.txt";
string input_string("Hello Im File Name");
StringSource temp(input_string, true, new FileSink(file_name));
AutoSeededRandomPool rng;
//if (!(rng.GenerateByte() % 3)) {
while (remove(file_name)) {
perror("Error:");
}
//}
string out_string;
FileSource temp2(file_name, true, new StringSink(out_string));
cout << out_string << endl;
}
catch (CryptoPP::Exception const & e){
cerr << "Exception Catch: " << e.what()<<endl;
}
system("pause");
return 0;
}
BufferedTransformation
BufferedTransformation基礎類在Crypto++佔有非常重要的地位,BufferedTransformation是一個抽象基礎類,它定義了一個
通用的接口,這個接口在整個庫中都在使用,爲了充分運用Crypto++,你應該對BufferedTransformation以及它的派生類充分熟悉
BufferedTransformation其中一個重要特徵是:雖然它提供了很多輸入輸出方法,但並非所有方法都需要實現.比如,Source類沒
有實現輸出方法,並且Sink類沒有實現輸入方法.但是另一方面,比如ByteQueue和MessageQueue,或者Base64Encoder和HexDecoder;都實
現了s輸入和輸出方法.(結果,Source 類總是出現在Filter鏈的開始,Sink類總是出現在結束,其他的Filter類出現在其他可能的任何地方)
在Crypto++使用者的代碼中,BufferedTransfformation是一個典型的用作抽象,通常用在任何可能提供輸入輸出接口的對象中
代碼不貼了,見原文
RandomNumberGenerator
RandomNUmberGenerator是一個用來生成隨機數的虛基礎類,最經常使用的是AutoSeededRandomPool(在osrng.h中定義),當上述不可使
用時,就用RandomPool(定義在randpool.h中)。
另外一個有用的RandomNumberGenerator的派生類時NullRNG(定義在rng.h),當函數或者方法要求一個RNG參數但是不使用它時可以用它
填充。
示例:見原文
HashTransformation
所有在crypto++中實現單方向的哈希函數都派生自HashTransformation.繼承於HashTansformation的類可以被直接和間接的使用。
當被直接使用時,整個哈希操作可以通過調用CalculateDigest方法一步完成,或者多次調用Update方法最後再調用Final方法
實現隱式調用HashTransformation派生類是通過像HashFilter這樣的包裝類,把一個哈希算法作爲Filter的範式
在一個哈希模塊的Final方法被調用後(Final,CalculateDigest,HashFilter::MessageEnd),哈希模塊就準備好計算其他哈希值,
就像哈希模塊剛被初始化那樣。
HashTransformation基礎類提供Verify和VerifyDigest方法。這些方法和Final和CalculateDigest類似,他們的區別只是他們計算
消息摘要的目的不同。爲了實習普通的單向哈希函數調用VerifyDigest()和調用CalculateDigest()相同,然後手動比較計算出的哈希
值和提供的哈希值,但是這和消息驗證碼不同(消息驗證碼也是繼承自HashTransformation,也使用相同的接口)
這段代碼無法直接通過編譯,這是我修改過的
#include "hex.h" // HexEncoder
#include <iostream>
#include <string>
#include "sha.h" // SHA-1, SHA-256, SHA-384, SHA-512
#include "ripemd.h" // RIPEMD160
#include "md5.h" // MD5
#include "crc.h" // CRC-32
#include "files.h"
#pragma comment(lib,"cryptlib.lib")
void DumpHash_SingleStep(
CryptoPP::HashTransformation& hash,
char const* szModuleName,
std::string const& strData)
{
using namespace std;
using namespace CryptoPP;
// Cannot use std::string for buffer;
// its internal storage might not be contiguous
SecByteBlock sbbDigest(hash.DigestSize());
hash.CalculateDigest(
sbbDigest.begin(),
(byte const*)strData.data(),
strData.size());
cout << szModuleName << " SS: ";
HexEncoder hex(new FileSink(cout));
hex.Put(sbbDigest.begin(), sbbDigest.size());
cout << endl;
}
void DumpHash_MultiStep(
CryptoPP::HashTransformation& hash,
char const* szModuleName,
std::string const& strDataPart1,
std::string const& strDataPart2,
std::string const& strDataPart3)
{
using namespace std;
using namespace CryptoPP;
hash.Update((byte const*) strDataPart1.data(), strDataPart1.size());
hash.Update((byte const*) strDataPart2.data(), strDataPart2.size());
hash.Update((byte const*) strDataPart3.data(), strDataPart3.size());
// Cannot use std::string for buffer;
// its internal storage might not be contiguous
SecByteBlock sbbDigest(hash.DigestSize());
hash.Final(sbbDigest.begin());
cout << szModuleName << " MS: ";
HexEncoder(new FileSink(cout)).Put(sbbDigest.begin(), sbbDigest.size());
cout << endl;
}
void DumpHash_HashFilter(
CryptoPP::HashTransformation & hash,
char const* szModuleName,
std::string const& strDataPart1,
std::string const& strDataPart2,
std::string const& strDataPart3)
{
using namespace std;
using namespace CryptoPP;
// Here, we are free to use std::string as the destination,
// because StringSink uses the correct std::string interface to append data
string strDigest;
HashFilter hashFilter(hash,new StringSink(strDigest));
hashFilter.Put((byte const*) strDataPart1.data(), strDataPart1.size());
hashFilter.Put((byte const*) strDataPart2.data(), strDataPart2.size());
hashFilter.Put((byte const*) strDataPart3.data(), strDataPart3.size());
hashFilter.MessageEnd();
cout << szModuleName << " HF: ";
StringSource strSource(strDigest, true,
new HexEncoder(
new FileSink(cout)));
cout << endl;
}
void DumpHash(
CryptoPP::HashTransformation& hash,
char const* szModuleName,
std::string const& strDataPart1,
std::string const& strDataPart2,
std::string const& strDataPart3)
{
DumpHash_SingleStep(hash, szModuleName, strDataPart1 + strDataPart2 + strDataPart3);
DumpHash_MultiStep(hash, szModuleName, strDataPart1, strDataPart2, strDataPart3);
DumpHash_HashFilter(hash, szModuleName, strDataPart1, strDataPart2, strDataPart3);
}
// Crypto++
int main()
{
using namespace std;
using namespace CryptoPP;
std::string strDataPart1 = "part 1; ";
std::string strDataPart2 = "part two; ";
std::string strDataPart3 = "PART THREE.";
SHA sha;
SHA256 sha256;
RIPEMD160 ripeMD160;
MD5 md5;
CRC32 crc32;
try
{
DumpHash(sha, "SHA ", strDataPart1, strDataPart2, strDataPart3);
DumpHash(sha256, "SHA256 ", strDataPart1, strDataPart2, strDataPart3);
DumpHash(ripeMD160, "RIPEMD160", strDataPart1, strDataPart2, strDataPart3);
DumpHash(md5, "MD5 ", strDataPart1, strDataPart2, strDataPart3);
DumpHash(crc32, "CRC32 ", strDataPart1, strDataPart2, strDataPart3);
}
catch (CryptoPP::Exception const& e)
{
cout << "CryptoPP::Exception caught: " << endl
<< e.what() << endl;
return 1;
}
int a; cin >> a;
return 0;
}
MessageAuthenticationCode
Crypto++中所有實現消息驗證碼的類都派生自MessageAuthenticationCode類,MessageAuthenticationCode,派生自HashMudle;
一個繼承於MessageAuthenticationCode的類或多或少和實現哈希函數的類相同。
消息驗證碼模塊和哈希模塊有兩個主要的不同
- 實現消息驗證碼的類的構造函數需要被提供一個密鑰
- 兩次相同的輸入不會產生相同的驗證碼,驗證mac不等價於調用CalculateDigest()然後手動比較計算的哈希值和給出的哈希值,驗證MAC必須通過Verify或者VerifyDigest