1. 程式人生 > >Crypto++ 加/解密演算法庫

Crypto++ 加/解密演算法庫

編譯 Crypto++ cryptlib 適合VC6 VC7 VC8 VC9 VC10

Crypto++ Library is a free C++ class library of cryptographic schemes.
可以到下面的網址下載最新原始碼:

Crypto++ Library 是開源的、跨平臺的C++, 提供豐富的加密解密演算法,包括:MD5,IDEA, Triple-DES,AES (Rijndael), RC6, MARS, Twofish, Serpent, RSA, DSA, SHA-1, SHA-2 等等。

支援的編譯器如下:

  * MSVC 6.0 - 2010
  * GCC 3.3 - 4.5
  * C++Builder 2010
  * Intel C++ Compiler 9 - 11.1
  * Sun Studio 12u1, Express 11/08, Express 06/10

==============================

這裡簡單說明一下使用 MSVC2008 對Crypto++進行編譯使用的方法和注意事項, 希望對大家開始學習有幫助!

下面一段的英文比較簡單, 說明了Crypto++包含的工程情況, 以及使用注意事項, 一看就清楚:

On Windows, Crypto++ can be compiled into 3 forms:a static library
including all algorithms, a DLL with only FIPS Approved algorithms, and
a static library with only algorithms not in the DLL.

To compile Crypto++ with MSVC, open the "cryptest.dsw" (for MSVC 6 and MSVC .NET
2003) or "cryptest.sln" (for MSVC 2005 - 2010) workspace file and build one or
more of the following projects:

//用於生成包含所有演算法的靜態庫

cryptlib - a static libraryincluding all algorithms

//用於生成僅包含FIPS作為標準的演算法的dll和匯入庫

cryptopp - This builds the DLL. Please note that if you wish to use Crypto++
  as a FIPS validated module, you must use a pre-built DLL that has undergone
  the FIPS validation process instead of building your own.
 

//基於dll開發的例子程式
dlltest - This builds a sample application that only uses the DLL.

//基於cryptlib靜態庫開發的測試驅動程式

cryptest Non-DLL-Import Configuration - This builds the full static library
  along with a full test driver.

//基於dll 和不包含FIPS法靜態庫開發的測試驅動程式

cryptest DLL-Import Configuration - This builds a static library containing
  only algorithms not in the DLL, along with a full test driver that uses
  both the DLL and the static library.

To use the Crypto++ DLL in your application, #include "dll.h" before including
any other Crypto++ header files, and place the DLL in the same directory as
your .exe file. dll.h includes the line #pragma comment(lib, "cryptopp")
so you don't have to explicitly list the import library in your project
settings.

To use a static library form of Crypto++, make the "cryptlib"
project a dependency of your application project, or specify it as
an additional library to link with in your project settings.
In either case you should check the compiler options to
make sure that the library and your application are using the same C++
run-time libraries and calling conventions.

名詞解釋:

FIPS : Federal Information Processing Standards   (美國)聯邦資訊處理標準

================================================================

crypto++ Crypto++是一個C++編寫的密碼學類庫,md5 AES DES 所有密碼加密的演算法都可找到,跨平臺

Crypto++是一個C++編寫的密碼學類庫。讀過《過河卒》的朋友還記得作者的那個不願意去微軟工作的兒子嗎,就是Crypto++的作者Wei Dai。
Crypto++是一個非常強大的密碼學庫,在密碼學界很受歡迎,最初還是Rivest(RSA的R)門下的一個博士姐姐把這個庫介紹給我的。雖然網路上可以找到很多密碼學相關的程式碼和庫,但是Crypto++有其明顯的優點。主要是功能全,統一性好。例如橢圓曲線加密演算法和AES在OpenSSL的crypto庫中就還沒最終完成,而在Crypto++中就支援的比較好,基本上密碼學中需要的主要功能都可以在裡面找得到。Crypto++是由標準的C++寫成的,學習C++、密碼學、網路安全都可以通過閱讀Crypto++的原始碼得到啟發和提高。

Crypto++的安裝
首先到http://www.cryptopp.com/
上下載最新版本的原始碼,如果是windows版的,會得到一個VC的專案,直接用VC開啟就可以編譯了。這裡建議大家使用最新版的C++編譯器,因為諸如VC6的編譯器是不支援C++的標準的,很多符合C++標準的程式碼不能編譯通過。編譯的時間比較長,完成後會生成cryptlib.lib這個庫檔案。可以將Crypto++原始檔的目錄命名為cryptopp,拷貝到編譯器的include目錄(例如:C:/VS.NET/VC7/include),將cryptlib.lib檔案拷貝到編譯器的lib目錄。這樣我們只需要說明連結cryptlib.lib即可。例如在VC7中在專案->屬性->連結器->命令列->附加選項中新增“cryptlib.lib”。

Hello World
現在寫一個hello world程式看看能不能編譯通過。

#include <iostream>
using namespace std;

#include <cryptopp/aes.h>
using namespace CryptoPP;

int main()
{
       cout << "hello crypto++" << endl;
       cout << "Aes block size is " << AES::BLOCKSIZE << endl;

 return 0;
}

編譯執行,一切OK,哈哈:D,可以用了。

Crypto++首頁上提供了Crypto++ User Guide這個入門指南的連結,這本指南屬於一定要看的資料,不過可惜的是這也是找到的唯一一本指南了:(。User Guide上面的有一些例子,其中對AES用法的說明不太直接,而AES之類對稱加密演算法又比較常用,所以我這裡寫了一個AES的例子。

例子是直接用AES加密一個塊,AES的資料塊大小為128位,金鑰長度可選擇128位、192位或256位。直接用AES加密一個塊很少用,因為我們平常都是加密任意長度的資料,需要選擇CFB等加密模式。但是直接的塊加密是對稱加密的基礎。

#include <iostream>
using namespace std;

#include <cryptopp/aes.h>
using namespace CryptoPP;

int main()
{

        //AES中使用的固定引數是以類AES中定義的enum資料型別出現的,而不是成員函式或變數
        //因此需要用::符號來索引

        cout << "AES Parameters: " << endl;
        cout << "Algorithm name : " << AES::StaticAlgorithmName() << endl;     

        //Crypto++庫中一般用位元組數來表示長度,而不是常用的位元組數
        cout << "Block size     : " << AES::BLOCKSIZE * 8 << endl;
        cout << "Min key length : " << AES::MIN_KEYLENGTH * 8 << endl;
        cout << "Max key length : " << AES::MAX_KEYLENGTH * 8 << endl;

        //AES中只包含一些固定的資料,而加密解密的功能由AESEncryption和AESDecryption來完成
        //加密過程
        AESEncryption aesEncryptor; //加密器

        unsigned char aesKey[AES::DEFAULT_KEYLENGTH];                   //金鑰

        unsigned char inBlock[AES::BLOCKSIZE] = "123456789";    //要加密的資料塊

        unsigned char outBlock[AES::BLOCKSIZE];                                 //加密後的密文塊

        unsigned char xorBlock[AES::BLOCKSIZE];                                 //必須設定為全零

        memset( xorBlock, 0, AES::BLOCKSIZE );                                 //置零

        aesEncryptor.SetKey( aesKey, AES::DEFAULT_KEYLENGTH );  //設定加密金鑰

        aesEncryptor.ProcessAndXorBlock( inBlock, xorBlock, outBlock ); //加密

        //以16進位制顯示加密後的資料

        for( int i=0; i<16; i++ ) {

                cout << hex << (int)outBlock[i] << " ";

        }

        cout << endl;

        //解密

        AESDecryption aesDecryptor;

        unsigned char plainText[AES::BLOCKSIZE];

        aesDecryptor.SetKey( aesKey, AES::DEFAULT_KEYLENGTH );

        aesDecryptor.ProcessAndXorBlock( outBlock, xorBlock, plainText );

        for( int i=0; i<16; i++ ) {      cout << plainText[i];    }
        cout << endl;

        return 0;
}


這裡面有幾個地方要注意一下:
AES並不是一個類,而是類Rijndael的一個typedef。
Rijndael雖然是一個類,但是其用法和namespace很像,本身沒有什麼成員函式和成員變數,只是在類體裡面定義了一系列的類和資料型別(enum),真正能夠進行加密解密的AESEncryption和AESDecryption都是定義在這個類內部的類。
AESEncryption和AESDecryption除了可以用SetKey()這個函式設定金鑰,在建構函式中也能設定金鑰,引數和SetKey()是一樣的。
ProcessAndXorBlock()可能會讓人比較疑惑,函式名的意思是ProcessBlock and XorBlock,ProcessBlock就是對塊進行加密或解密,XorBlock在各種加密模式中有用,這裡我們不需要應用模式,因此把用來Xor操作的xorBlock置為0,那麼Xor操作就不起作用了。