• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            流量統(tǒng)計(jì):
            Rixu Blog (日需博客)
            日需博客,每日必需來(lái)踩踩哦..
            posts - 108,comments - 54,trackbacks - 0
            背景(只是個(gè)人感想,技術(shù)上不對(duì)后面的內(nèi)容構(gòu)成知識(shí)性障礙,可以skip):

            最近,基于某些原因和需要,筆者需要去了解一下Crypto++庫(kù),然后對(duì)一些數(shù)據(jù)進(jìn)行一些加密解密的操作。

            筆者之前沒(méi)接觸過(guò)任何加密解密方面的知識(shí)(當(dāng)然,把每個(gè)字符的ASCII值加1之流對(duì)明文進(jìn)行加密的“趣事”還是干過(guò)的,當(dāng)時(shí)還很樂(lè)在其中。),甚至一開(kāi)始連Crypto++的名字都沒(méi)有聽(tīng)過(guò),被BS了之后,就開(kāi)始了Crypto++的入門(mén)探索過(guò)程。

            最初,大概知道了要了解兩大類(lèi)算法中的幾個(gè)算法——對(duì)稱(chēng)加密算法:DES、AES(后來(lái)因?yàn)槿似泛玫木壒室擦私饬讼路菍?duì)稱(chēng)加密算法RSA,后文會(huì)詳述何謂“人品好”);散列算法(需要通過(guò)Hash運(yùn)算):SHA-256。

            起初,筆者以為這樣的知名算法在網(wǎng)上應(yīng)該有很多現(xiàn)成的例子。筆者比較懶,對(duì)于自己不熟悉的東西,總希望找捷徑,直接找別人現(xiàn)(在已經(jīng)寫(xiě))成可(編譯運(yùn))行的代碼然后施展ctrl + C,ctrl + V算法(咳,什么算法,是大法!!!)。

            However,發(fā)覺(jué)網(wǎng)上的例子不是稀缺,就是只有代碼沒(méi)有解釋。筆者覺(jué)得很難忍受這樣的“莫名其妙”(奇怪的是筆者容忍了windows了,盡管它不開(kāi)源),遂決定從零開(kāi)始……

             

            ……寫(xiě)在代碼前……


                  如果之前像筆者一樣沒(méi)相關(guān)經(jīng)驗(yàn)——完全沒(méi)接觸過(guò)加密解密——,請(qǐng)務(wù)必閱讀下文。
             

            一些前期工作——編譯cryptlib并使其可用:

                  本文不涉及這部分內(nèi)容,因?yàn)橐呀?jīng)有相對(duì)完善的資料:
                    http://www.cnblogs.com/cxun/archive/2008/07/30/743541.html

             

            總結(jié)了一點(diǎn)預(yù)備知識(shí):

            關(guān)于幾個(gè)算法的介紹,網(wǎng)上各大百科都有,筆者不再詳細(xì)Ctrl+C/V了。不過(guò)在寫(xiě)代碼之前,即使復(fù)制修改人家代碼之前,也有必要了解一下幾個(gè)算法(除了名稱(chēng)之外)的使用流程(不是算法具體的實(shí)現(xiàn),汗!)。

             

            對(duì)稱(chēng)加密:(AES、DES)

            相對(duì)于與非對(duì)稱(chēng)加密而言,加密、解密用的密匙相同就像日常生活中的鑰匙,開(kāi)門(mén)和鎖門(mén)都是同一把。

            詳見(jiàn):http://baike.baidu.com/view/119320.htm

             

            非對(duì)稱(chēng)加密:(RSA)

            相對(duì)于上述的對(duì)稱(chēng)加密而言,加密、解密用的密匙不同有公匙和私匙之分。

            詳見(jiàn):http://baike.baidu.com/view/554866.htm 


            散列算法:(SHA系列,我們熟悉的MD5等)

            用途:驗(yàn)證信息有沒(méi)有被修改。

            原理:對(duì)長(zhǎng)度大的信息進(jìn)行提煉(通過(guò)一個(gè)Hash函數(shù)),提煉過(guò)后的信息長(zhǎng)度小很多,得到的是一個(gè)固定長(zhǎng)度的值(Hash值)。對(duì)于兩個(gè)信息量很大的文件通過(guò)比較這兩個(gè)值,就知道這兩個(gè)文件是否完全一致(另外一個(gè)文件有沒(méi)有被修改)。從而避免了把兩個(gè)文件中的信息進(jìn)行逐字逐句的比對(duì),減少時(shí)間開(kāi)銷(xiāo)。

            形象地描述:鬼泣3里面維吉爾跟但丁除了發(fā)型之外都很像。怎么區(qū)分兩個(gè)雙生子?比較他們的DNA就好比是比較信息量很大的文件,然而直接看發(fā)型就好比是看Hash值。一眼就看出來(lái)了。

             

            注:以上是筆者對(duì)幾個(gè)概念的,非常不嚴(yán)格的,非常主觀(guān)的,概括的描述,想要詳細(xì)了解,可以:

            http://wenku.baidu.com/view/4fb8e0791711cc7931b716aa.html

            幾個(gè)算法的介紹,選擇,比較。

             

             

             

            ……Code speaking……

             

            平臺(tái):WindowsXP

            IDE以及工具:Visual Studio 2008 + Visual Assist

            庫(kù)版本:Crypto++ 5.6.0

             

             

            庫(kù)的文檔(包括類(lèi)和函數(shù)的接口列表):
            http://www.cryptopp.com/docs/ref/index.html

             

             

            對(duì)稱(chēng)加密算法:

            DES:

            一開(kāi)始筆者并沒(méi)有找到關(guān)于DES運(yùn)用的很好的例程,或者說(shuō),筆者的搜索功力薄弱,未能找到非常完整的例程吧。

            http://bbs.pediy.com/showthread.php?p=745389

            筆者以下的代碼主要是參考上面URL的論壇回帖,但是作了些修改:

             

             1#include <iostream>
             2#include <des.h>
             3
             4#pragma comment( lib, "cryptlib.lib" )
             5
             6using namespace std;
             7using namespace CryptoPP;
             8
             9int main( void )
            10{
            11    //主要是打印一些基本信息,方便調(diào)試:
            12    cout << "DES Parameters: " << endl;
            13    cout << "Algorithm name : " << DES::StaticAlgorithmName() << endl; 
            14    
            15    unsigned char key[ DES::DEFAULT_KEYLENGTH ];
            16    unsigned char input[ DES::BLOCKSIZE ] = "12345";
            17    unsigned char output[ DES::BLOCKSIZE ];
            18    unsigned char txt[ DES::BLOCKSIZE ];
            19
            20    cout << "input is: " << input << endl;
            21
            22    //可以理解成首先構(gòu)造一個(gè)加密器
            23    DESEncryption encryption_DES;
            24
            25    //回憶一下之前的背景,對(duì)稱(chēng)加密算法需要一個(gè)密匙。加密和解密都會(huì)用到。
            26    //因此,設(shè)置密匙。
            27    encryption_DES.SetKey( key, DES::KEYLENGTH );
            28    //進(jìn)行加密
            29    encryption_DES.ProcessBlock( input, output );
            30
            31    //顯示結(jié)果
            32    //for和for之后的cout可有可無(wú),主要為了運(yùn)行的時(shí)候看加密結(jié)果
            33    //把字符串的長(zhǎng)度寫(xiě)成一個(gè)常量其實(shí)并不被推薦。
            34    //不過(guò)筆者事先知道字符串長(zhǎng),為了方便調(diào)試,就直接寫(xiě)下。
            35    //這里主要是把output也就是加密后的內(nèi)容,以十六進(jìn)制的整數(shù)形式輸出。
            36    forint i = 0; i < 5; i++ )
            37    {
            38        cout << hex << (int)output[ i ] << ends;
            39    }

            40    cout << endl;
            41
            42    //構(gòu)造一個(gè)加密器
            43    DESDecryption decryption_DES;    
            44
            45    //由于對(duì)稱(chēng)加密算法的加密和解密都是同一個(gè)密匙,
            46    //因此解密的時(shí)候設(shè)置的密匙也是剛才在加密時(shí)設(shè)置好的key
            47    decryption_DES.SetKey( key, DES::KEYLENGTH );
            48    //進(jìn)行解密,把結(jié)果寫(xiě)到txt中
            49    //decryption_DES.ProcessAndXorBlock( output, xorBlock, txt );
            50    decryption_DES.ProcessBlock( output, txt );
            51
            52    //以上,加密,解密還原過(guò)程已經(jīng)結(jié)束了。以下是為了驗(yàn)證:
            53    //加密前的明文和解密后的譯文是否相等。
            54    if ( memcmp( input, txt, 5 ) != 0 )
            55    {
            56        cerr << "DES Encryption/decryption failed.\n";
            57        abort();
            58    }

            59    cout << "DES Encryption/decryption succeeded.\n";
            60    
            61    return 0;
            62}

            63

             回想一下以上代碼的編寫(xiě)過(guò)程,就可以發(fā)現(xiàn),進(jìn)行DES加密,流程大概是:
                   數(shù)據(jù)準(zhǔn)備;
                   構(gòu)造加密器;
                   設(shè)置加密密匙;
                   加密數(shù)據(jù);
                   顯示(非必要);
                   設(shè)置解密密匙(跟加密密匙是同一個(gè)key);
                   解密數(shù)據(jù);
                   驗(yàn)證與顯示(非必要);
                   由此可見(jiàn),主要函數(shù)的調(diào)用流程就是這樣。但是文檔沒(méi)有詳細(xì)講,筆者當(dāng)時(shí)打開(kāi)下載回來(lái)的源文件時(shí),就傻了眼。
            猜想:
                   AES和以后的算法,是不是都是按照這些基本的套路呢?


                   AES:    

                   在實(shí)際運(yùn)用的時(shí)候,從代碼上看,AES跟DES非常相像。但是值得注意一點(diǎn)的是,AES取代了DES成為21世紀(jì)的加密標(biāo)準(zhǔn)。是因?yàn)橐云涿艹组L(zhǎng)度和高安全性獲得了先天優(yōu)勢(shì)。雖然界面上看上去沒(méi)多大區(qū)別,但是破解難度遠(yuǎn)遠(yuǎn)大于DES。詳細(xì)情況,在之前的URL有提及過(guò)。
                 
                   很幸運(yùn),筆者很快就找到了AES的使用例程,而且很詳細(xì):
                  http://dev.firnow.com/course/3_program/c++/cppsl/2008827/138033.html

             1#include <iostream>
             2#include <aes.h>
             3
             4#pragma comment( lib, "cryptlib.lib" )
             5
             6using namespace std; 
             7using namespace CryptoPP;
             8
             9int main()
            10{
            11
            12    //AES中使用的固定參數(shù)是以類(lèi)AES中定義的enum數(shù)據(jù)類(lèi)型出現(xiàn)的,而不是成員函數(shù)或變量
            13    //因此需要用::符號(hào)來(lái)索引
            14    cout << "AES Parameters: " << endl;
            15    cout << "Algorithm name : " << AES::StaticAlgorithmName() << endl;      
            16
            17    //Crypto++庫(kù)中一般用字節(jié)數(shù)來(lái)表示長(zhǎng)度,而不是常用的字節(jié)數(shù)
            18    cout << "Block size     : " << AES::BLOCKSIZE * 8 << endl;
            19    cout << "Min key length : " << AES::MIN_KEYLENGTH * 8 << endl;
            20    cout << "Max key length : " << AES::MAX_KEYLENGTH * 8 << endl;
            21
            22    //AES中只包含一些固定的數(shù)據(jù),而加密解密的功能由AESEncryption和AESDecryption來(lái)完成
            23    //加密過(guò)程
            24    AESEncryption aesEncryptor; //加密器 
            25
            26    unsigned char aesKey[AES::DEFAULT_KEYLENGTH];  //密鑰
            27    unsigned char inBlock[AES::BLOCKSIZE] = "123456789";    //要加密的數(shù)據(jù)塊
            28    unsigned char outBlock[AES::BLOCKSIZE]; //加密后的密文塊
            29    unsigned char xorBlock[AES::BLOCKSIZE]; //必須設(shè)定為全零
            30
            31    memset( xorBlock, 0, AES::BLOCKSIZE ); //置零
            32
            33    aesEncryptor.SetKey( aesKey, AES::DEFAULT_KEYLENGTH );  //設(shè)定加密密鑰
            34    aesEncryptor.ProcessAndXorBlock( inBlock, xorBlock, outBlock );  //加密
            35
            36    //以16進(jìn)制顯示加密后的數(shù)據(jù)
            37    forint i=0; i<16; i++ ) {
            38        cout << hex << (int)outBlock[i] << " ";
            39    }

            40    cout << endl;
            41
            42    //解密
            43    AESDecryption aesDecryptor;
            44    unsigned char plainText[AES::BLOCKSIZE];
            45
            46    aesDecryptor.SetKey( aesKey, AES::DEFAULT_KEYLENGTH );
            47    //細(xì)心的朋友注意到這里的函數(shù)不是之前在DES中出現(xiàn)過(guò)的:ProcessBlock,
            48    //而是多了一個(gè)Xor。其實(shí),ProcessAndXorBlock也有DES版本。用法跟AES版本差不多。
            49    //筆者分別在兩份代碼中列出這兩個(gè)函數(shù),有興趣的朋友可以自己研究一下有何差異。
            50    aesDecryptor.ProcessAndXorBlock( outBlock, xorBlock, plainText );
            51
            52
            53    forint i=0; i<16; i++ ) 
            54    {      
            55        cout << plainText[i];   
            56    }

            57    cout << endl;
            58
            59    return 0;
            60}

            61
            62


            其實(shí)來(lái)到這里,都可以發(fā)現(xiàn),加密解密的套路也差不多,至于之后筆者在誤打誤撞中找到的RSA,也只不過(guò)是在設(shè)置密匙的時(shí)候多了私匙和公匙的區(qū)別而已。筆者總覺(jué)得,有完整的例程對(duì)照學(xué)習(xí),是一件很幸福的事情。

             

            非對(duì)稱(chēng)加密算法:

            RSA:

            小背景:
                   其實(shí),筆者在一開(kāi)始并沒(méi)有接到“了解RSA”的要求。不過(guò)由于筆者很粗心,在看AES的時(shí)候只記得A和S兩個(gè)字母,Google的時(shí)候就誤打誤撞Google了一個(gè)RSA。其實(shí)RSA方面的資料還是挺多的,因此它事實(shí)上是筆者第一個(gè)編譯運(yùn)行成功的Crypto++庫(kù)中算法的應(yīng)用實(shí)例。
                   
                     http://www.cnblogs.com/cxun/archive/2008/07/30/743541.html
                   以下代碼主要是按照上述URL中提供的代碼寫(xiě)成的,作為筆者的第一份有效學(xué)習(xí)資料,筆者認(rèn)為作為調(diào)用者的我們,不用清楚算法實(shí)現(xiàn)的細(xì)節(jié)。只需要明白幾個(gè)主要函數(shù)的功用和調(diào)用的次序即可。
                   由以下代碼可以看出,其實(shí)RSA也離不開(kāi):數(shù)據(jù)準(zhǔn)備、設(shè)置密匙(注意,有公匙和私匙)、加密解密這樣的套路。至于如何產(chǎn)生密匙,有興趣的朋友可以到Crypto++的主頁(yè)上下載源文件研究。作為入門(mén)和了解階段,筆者覺(jué)得:只需要用起來(lái)即可。

              1//version at Crypto++ 5.60
              2#include "randpool.h"
              3#include "rsa.h"
              4#include "hex.h"
              5#include "files.h"
              6#include <iostream>
              7
              8using namespace std;
              9using namespace CryptoPP;
             10
             11#pragma comment(lib, "cryptlib.lib")
             12
             13
             14//------------------------
             15
             16// 函數(shù)聲明
             17
             18//------------------------
             19
             20void GenerateRSAKey( unsigned int keyLength, const char *privFilename, const char *pubFilename, const char *seed  );
             21string RSAEncryptString( const char *pubFilename, const char *seed, const char *message );
             22string RSADecryptString( const char *privFilename, const char *ciphertext );
             23RandomPool & GlobalRNG();
             24
             25//------------------------
             26// 主程序
             27//------------------------
             28
             29void main( void )
             30
             31{
             32    char priKey[ 128 ] = 0 };
             33    char pubKey[ 128 ] = 0 };
             34    char seed[ 1024 ]  = 0 };
             35
             36    // 生成 RSA 密鑰對(duì)
             37    strcpy( priKey, "pri" );  // 生成的私鑰文件
             38    strcpy( pubKey, "pub" );  // 生成的公鑰文件
             39    strcpy( seed, "seed" );
             40    GenerateRSAKey( 1024, priKey, pubKey, seed );
             41
             42    // RSA 加解密
             43    char message[ 1024 ] = 0 };
             44    cout<< "Origin Text:\t" << "Hello World!" << endl << endl;
             45    strcpy( message, "Hello World!" );
             46    string encryptedText = RSAEncryptString( pubKey, seed, message );  // RSA 公匙加密
             47    cout<<"Encrypted Text:\t"<< encryptedText << endl << endl;
             48    string decryptedText = RSADecryptString( priKey, encryptedText.c_str() );  // RSA 私匙解密
             49}

             50
             51
             52
             53//------------------------
             54
             55// 生成RSA密鑰對(duì)
             56
             57//------------------------
             58
             59void GenerateRSAKey(unsigned int keyLength, const char *privFilename, const char *pubFilename, const char *seed)
             60{
             61    RandomPool randPool;
             62    randPool.Put((byte *)seed, strlen(seed));
             63
             64    RSAES_OAEP_SHA_Decryptor priv(randPool, keyLength);
             65    HexEncoder privFile(new FileSink(privFilename));
             66
             67    priv.DEREncode(privFile);
             68    privFile.MessageEnd();
             69
             70    RSAES_OAEP_SHA_Encryptor pub(priv);
             71    HexEncoder pubFile(new FileSink(pubFilename));
             72    pub.DEREncode(pubFile);
             73
             74    pubFile.MessageEnd();
             75
             76    return ;
             77}

             78
             79
             80
             81//------------------------
             82
             83// RSA加密
             84
             85//------------------------
             86
             87string RSAEncryptString( const char *pubFilename, const char *seed, const char *message )
             88{
             89    FileSource pubFile( pubFilename, truenew HexDecoder );
             90    RSAES_OAEP_SHA_Encryptor pub( pubFile );
             91
             92    RandomPool randPool;
             93    randPool.Put( (byte *)seed, strlen(seed) );
             94
             95    string result;
             96    StringSource( message, truenew PK_EncryptorFilter(randPool, pub, new HexEncoder(new StringSink(result))) );
             97    
             98    return result;
             99}

            100
            101
            102
            103//------------------------
            104// RSA解密
            105//------------------------
            106
            107string RSADecryptString( const char *privFilename, const char *ciphertext )
            108{
            109    FileSource privFile( privFilename, truenew HexDecoder );
            110    RSAES_OAEP_SHA_Decryptor priv(privFile);
            111
            112    string result;
            113    StringSource( ciphertext, truenew HexDecoder(new PK_DecryptorFilter(GlobalRNG(), priv, new StringSink(result))) );
            114
            115    return result;
            116}

            117
            118
            119
            120//------------------------
            121
            122// 定義全局的隨機(jī)數(shù)池
            123
            124//------------------------
            125
            126RandomPool & GlobalRNG()
            127{
            128    static RandomPool randomPool;
            129    return randomPool;
            130}

            131
            132


             

            散列算法:


            SHA-256                                                                                                                                                                                                                                                                      

                   SHA-256主要是用來(lái)求一大段信息的Hash值,跟之前三個(gè)用于加密、解密的算法有所不同。用到SHA的場(chǎng)合,多半是為了校驗(yàn)文件。
                   
                     筆者的參考資料:http://hi.baidu.com/magic475/blog/item/19b37a8c1fa15a14b21bbaeb.html
                   請(qǐng)注意,筆者在實(shí)現(xiàn)的時(shí)候,稍微修改了一下兩個(gè)子函數(shù)的實(shí)現(xiàn),以滿(mǎn)足筆者的需求。因此會(huì)與上述URL中的代碼有差異。

              1//http://hi.baidu.com/magic475/blog/item/19b37a8c1fa15a14b21bbaeb.html
              2#include <iostream>
              3#include <string.h>
              4
              5#include "sha.h"
              6#include "secblock.h"
              7#include "modes.h"
              8#include "hex.h"
              9
             10#pragma comment( lib, "cryptlib.lib")
             11
             12using namespace std;
             13using namespace CryptoPP;
             14
             15void CalculateDigest(string &Digest, const string &Message);
             16bool VerifyDigest(const string &Digest, const string &Message);
             17
             18int main( void )
             19{
             20    //main函數(shù)中注釋掉的,關(guān)于strMessage2的代碼,其實(shí)是筆者模擬了一下
             21    //通過(guò)求Hash值來(lái)對(duì)“大”量數(shù)據(jù)進(jìn)行校驗(yàn)的這個(gè)功能的運(yùn)用。
             22    //注釋之后并不影響這段代碼表達(dá)的思想和流程。
             23    string strMessage( "Hello world" );
             24    string strDigest;
             25    //string strMessage2( "hello world" ); //只是第一個(gè)字母不同
             26    //string strDigest2;
             27
             28    CalculateDigest( strDigest, strMessage );  //計(jì)算Hash值并打印一些debug信息
             29    cout << "the size of Digest is: " << strDigest.size() << endl;
             30    cout << "Digest is: " << strDigest << endl;
             31
             32    //CalculateDigest( strDigest2, strMessage2 );
             33    //why put this function here will affect the Verify function?
             34    //作者在寫(xiě)代碼的過(guò)程中遇到的上述問(wèn)題。
             35    //如果把這行代碼的注釋取消,那么之后的運(yùn)行結(jié)果就不是預(yù)料中的一樣:
             36    //即使strDigest也無(wú)法對(duì)應(yīng)strMessage,筆者不知道為什么,希望高手指出,謝謝!
             37
             38    bool bIsSuccess = false;
             39    bIsSuccess = VerifyDigest( strDigest, strMessage ); 
             40    //通過(guò)校驗(yàn),看看strDigest是否對(duì)應(yīng)原來(lái)的message
             41    if( bIsSuccess )
             42    {
             43        cout << "sussessive verify" << endl;
             44        cout << "origin string is: " << strMessage << endl << endl;
             45    }

             46    else
             47    {
             48        cout << "fail!" << endl;
             49    }

             50
             51    //通過(guò)strDigest2與strMessage進(jìn)行校驗(yàn),要是相等,
             52    //就證明strDigest2是對(duì)應(yīng)的strMessage2跟strMessage1相等。
             53    //否則,像這個(gè)程序中的例子一樣,兩個(gè)message是不相等的
             54    /*CalculateDigest( strDigest2, strMessage2 );
             55    bIsSuccess = VerifyDigest( strDigest2, strMessage );
             56    if( !bIsSuccess )
             57    {
             58        cout << "success! the tiny modification is discovered~" << endl;
             59        cout << "the origin message is: \n" << strMessage << endl;
             60        cout << "after modify is: \n" << strMessage2 << endl;
             61    }*/

             62    return 0;
             63}

             64
             65
             66//基于某些原因,以下兩個(gè)子函數(shù)的實(shí)現(xiàn)跟原來(lái)參考代碼中的實(shí)現(xiàn)有所區(qū)別,
             67//詳細(xì)原因,筆者在CalculateDigest函數(shù)的注釋中寫(xiě)明
             68void CalculateDigest(string &Digest, const string &Message)
             69{
             70    SHA256 sha256;
             71    int DigestSize = sha256.DigestSize();
             72    char* byDigest;
             73    char* strDigest;
             74
             75    byDigest = new char[ DigestSize ];
             76    strDigest = new char[ DigestSize * 2 + 1 ];
             77
             78    sha256.CalculateDigest((byte*)byDigest, (const byte *)Message.c_str(), Message.size());
             79    memset(strDigest, 0sizeof(strDigest));
             80    //uCharToHex(strDigest, byDigest, DigestSize);
             81    //參考的代碼中有以上這么一行,但是貌似不是什么庫(kù)函數(shù)。
             82    //原作者大概是想把Hash值轉(zhuǎn)換成16進(jìn)制數(shù)保存到一個(gè)string buffer中,
             83    //然后在主程序中輸出,方便debug的時(shí)候?qū)φ詹榭础?br style="box-sizing: border-box; " />  84    //但是這并不影響計(jì)算Hash值的行為。
             85    //因此筆者注釋掉了這行代碼,并且修改了一下這個(gè)函數(shù)和后面的VerifyDigest函數(shù),
             86    //略去原作者這部分的意圖,繼續(xù)我們的程序執(zhí)行。
             87
             88    Digest = byDigest;
             89
             90    delete []byDigest;
             91    byDigest = NULL;
             92    delete []strDigest;
             93    strDigest = NULL;
             94
             95    return;
             96}

             97
             98bool VerifyDigest(const string &Digest, const string &Message)
             99{
            100    bool Result;
            101    SHA256 sha256;
            102    char* byDigest;
            103
            104    byDigest = new char[ sha256.DigestSize() ];
            105    strcpy( byDigest, Digest.c_str() );
            106
            107    //HexTouChar(byDigest, Digest.c_str(), Digest.size());
            108    //為何注釋掉,請(qǐng)參看CalculateDigest函數(shù)的注釋
            109    Result = sha256.VerifyDigest( (byte*)byDigest, (const byte *)Message.c_str(), Message.size() );
            110
            111    delete []byDigest;
            112    byDigest = NULL;
            113    return Result;
            114}

            115
            116




                    后記:
                    為什么寫(xiě)這篇文章呢?因?yàn)楣P者在搜索過(guò)程中覺(jué)得這方面的資料有點(diǎn)分散,因此想把它們集中起來(lái),方便剛剛?cè)腴T(mén)的朋友。
                     同時(shí),也算是為自己留點(diǎn)學(xué)習(xí)資料吧。
            Logo
            作者:Gezidan
            出處:http://www.rixu.net    
            本文版權(quán)歸作者和博客園共有,歡迎轉(zhuǎn)載,但未經(jīng)作者同意必須保留此段聲明,且在文章頁(yè)面明顯位置給出原文連接,否則保留追究法律責(zé)任的權(quán)利。
            posted on 2011-08-05 16:37 日需博客 閱讀(1806) 評(píng)論(0)  編輯 收藏 引用 所屬分類(lèi): C C++技術(shù)文章轉(zhuǎn)載
            日本人妻丰满熟妇久久久久久| 久久久91人妻无码精品蜜桃HD| 久久久久高潮综合影院| 中文字幕日本人妻久久久免费| 亚洲综合伊人久久大杳蕉| 国产午夜精品久久久久免费视| 精品久久久久久久| 三级韩国一区久久二区综合| 久久精品国产久精国产一老狼| 丰满少妇人妻久久久久久| 久久久久久亚洲精品不卡| 亚洲中文久久精品无码ww16| 亚洲国产精品久久久久网站| 亚洲国产精品狼友中文久久久| 亚洲精品无码久久久久| 99热热久久这里只有精品68| 精品国产乱码久久久久软件| 久久精品成人免费网站| 久久夜色精品国产噜噜亚洲a| 99久久婷婷国产综合亚洲| 婷婷久久综合| 久久99国产精品久久99| 久久天天躁狠狠躁夜夜不卡| 亚洲伊人久久大香线蕉苏妲己| 久久99精品久久久大学生| 国产真实乱对白精彩久久| 久久精品国产亚洲AV无码偷窥| 色欲综合久久躁天天躁| 久久综合丁香激情久久| 99久久国产宗和精品1上映 | 伊人久久综合无码成人网| 日韩精品久久久久久| 国产成人精品综合久久久久| 国产69精品久久久久99尤物| 久久丫精品国产亚洲av不卡| 久久久久久国产精品无码下载| 九九久久精品国产| 久久久精品一区二区三区| 亚洲国产精品无码久久一区二区 | 亚洲伊人久久大香线蕉苏妲己| 香蕉久久av一区二区三区|