UserGuide:cryptlib.h學習筆記(翻譯)

原文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的類或多或少和實現哈希函數的類相同。

消息驗證碼模塊和哈希模塊有兩個主要的不同

  1. 實現消息驗證碼的類的構造函數需要被提供一個密鑰
  2. 兩次相同的輸入不會產生相同的驗證碼,驗證mac不等價於調用CalculateDigest()然後手動比較計算的哈希值和給出的哈希值,驗證MAC必須通過Verify或者VerifyDigest
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章