• <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>

            woaidongmao

            文章均收錄自他人博客,但不喜標題前加-[轉貼],因其丑陋,見諒!~
            隨筆 - 1469, 文章 - 0, 評論 - 661, 引用 - 0
            數據加載中……

            Crypto 加密的基本流程

            前言:
                Crypto
            是微軟的加密API,如果看懂了,使用起來是很簡單的一件事,不過就是最開始沒有看懂,被虐了兩天。然后又被其他問題給虐了兩天。最后做出來的東西也不是讓自己十分滿意。不過還好,最后的結果還不算太糟。
               
            本想對代碼進行一次整理,寫一個demo代碼,不過現在有些慵懶了,還是隨便貼些筆記好了。

            PS   
               
            發現Delphi盒子要賣了。這似乎也驗證了一句話,有商業價值的東西才會有持續的生命力。

            Crypto 加密的基本流程

            1. 創建/獲取一個密碼容器CSP
            2. 創建/獲取/導入一個密鑰
            3. 使用密鑰進行加密/解密

            加密具體流程:

            1. 創建/獲取一個密碼容器CSP。這一部分基本上所有程序都一樣,直接復制過來到程序里就可以了。

            //以下獲得一個CSP句柄
                if(CryptAcquireContext(
                    &hProv,   //out
            密碼容器
                    NULL,                //NULL
            表示使用默認密鑰容器,默認密鑰容器名為用戶登陸名。
                    NULL,
                    PROV_RSA_FULL, //in
            使用RSA密鑰
                    0))
                {
                    printf("A cryptographic provider has been acquired. \n");
                }
                else//
            密鑰容器不存在
                {
                    if(CryptAcquireContext(
                        &hProv,
                        NULL,
                        NULL,
                        PROV_RSA_FULL,
                        CRYPT_NEWKEYSET))//
            創建密鑰容器
                    {
                        //
            創建密鑰容器成功,并得到CSP句柄
                        printf("A new key container has been created.\n");
                    }
                    else
                    {
                        HandleError("Could not create a new key container.\n");
                    }      
                }

            1. 創建/獲取一個密鑰。這里有些程序里會創建一個sessionKey會話密鑰用于對稱加密,這里創建的是非對稱加密的密鑰。

                //--------------------------------------------------------------------
                //
            從密鑰容器中取交換密鑰
                if(CryptGetUserKey(  
                    hProv,    //CSP
            句柄,也就是在一里面創建的,密碼容器。
                    AT_KEYEXCHANGE,    //
            密鑰的類型,這里指名的是交換密鑰。還有一個AT_SIGNATURE,這個是數字簽名用的。
                    &hKey)) //out
            獲取到的密鑰
                {
                    printf("The signature key has been acquired. \n");
                }
                else
                {
                    if(GetLastError() == NTE_NO_KEY) //
            密鑰容器里不存在key pair創建之
                    {
                        if(CryptGenKey(
                            hProv,            //in CSP
            句柄
                            AT_SIGNATURE,    //in
            創建的密鑰對類型為signature key pair
                            0,                //key
            類型,這里用默認值
                            &hKey))         //out
            創建成功返回新創建的密鑰對的句柄
                        {
                            printf("Created a signature key pair.\n");
                        }
                        else
                        {
                            MyHandleError("Error occurred creating a signature key.\n");
                        }
                    }
                    else
                    {
                        MyHandleError("Error during CryptGetUserKey for signkey.");
                    }
                }

            1. 使用密鑰進行加密

                    //--------------------------------------------------------------------
                    //
            加密數據
                    if(!CryptEncrypt(
                        hKey,            //in
            密鑰
                        0,                //
            如果數據同時進行散列和加密,這里傳入一個散列對象
                        TRUE,    //
            如果是最后一個被加密的塊,輸入TRUE.如果不是輸入FALSE.
                                        //
            這里通過判斷是否到文件尾來決定是否為最后一塊。
                        0,                //
            保留
                        pbBuffer,        // in/out
            輸入被加密數據,輸出加密后的數據。將pbBuffer分配大一些,防止長度不夠。
                        &dwCount,        // in/out
            輸入被加密數據實際長度,輸出加密后數據長度。這個需要根據pbBuffer的實際輸入長度進行計算(strlen?),不然不能正常運行。
                        dwBufferLen))    //in pbBuffer
            的大小。這里填大點,
                    {
                        HandleError("Error during CryptEncrypt. \n");
                    }
            到這里加密就已經做完了,加密后的數據保存在pbBuffer中。

            1. 導出公/私鑰

            私鑰在加密的時候需要,以后使用的時候不再生成,直接導入。(備注:如果需要導出私鑰需要在創建密鑰時候設置參數,具體見MSDN
            解密的時候需要用到公鑰,需要將公鑰分發給解密用戶。
                //--------------------------------------------------------------------
                //
            因為接收消息者要驗證數字簽名,所以要導出公鑰給接收者。
                if(CryptExportKey(  
                    hKey,  //in
            密鑰句柄
                    NULL,   
                    PUBLICKEYBLOB,// out
            公鑰輸出數據。在導出后,需要將公鑰的數據保存成文件等,以便分發。
                    0,   
                    NULL,
                    &dwBlobLen)) //out
            得到公鑰的大小
                {
                    printf("Size of the BLOB for the public key determined. \n");
                }
                else
                {
                    MyHandleError("Error computing BLOB length.");
                }

            1. 銷毀容器和Key

            在完成加密后,需要對key和容器進行銷毀,相關函數如下。
                if(hKey)
            CryptDestroyKey(hKey);
                if(hCryptProv)
            CryptReleaseContext(hCryptProv, 0);
            解密的具體流程:

            1. 同加密流程
            2. 導入解密用的公鑰。

                HCRYPTKEY hPubKey;
                if(CryptImportKey(
                    hProv,//in CSP
            密碼容器
                    pbKeyBlob,//in
            需要導入的公鑰數據(在加密的時候導出的公鑰,加密中的4
                    dwBlobLen,//in
            公鑰數據的長度
                    0,
                    0,
                    &hPubKey))//out
            公鑰導入得到的公鑰句柄
                {
                    printf("The key has been imported.\n");
                }
                else
                {
                    MyHandleError("Public key import failed.");
                }

            1. 解密

            解密的參數和加密的參數基本相同。
                    //--------------------------------------------------------------------
                    // Decrypt data.
                    if(!CryptDecrypt(
                        hPubKey, //in
            解密用的公鑰,也就是在2中導入的公鑰
                        0,
                       TRUE,    //
            如果是最后一個被加密的塊,輸入TRUE.如果不是輸入FALSE.
                        0,
                        pbBuffer,        // in/out
            輸入被解密數據,輸出加密后的數據。將pbBuffer分配大一些,防止長度不夠。
                        &dwCount))    // in/out
            輸入被解密數據實際長度,輸出加密后數據長度。這個需要根據pbBuffer的實際輸入長度進行計算(strlen?),不然不能正常運行。
                    {
                        HandleError("Error during CryptDecrypt!");
                    }

            1. 銷毀容器和Key

            同加密
            相關參考資料:
            學習CRYPTOAPI第一天(這個網站還有另外的兩篇 二/三天)    http://www.wangchao.org/bbsdetail_66820.html
            VC
            知識庫文檔中心(Microsoft CryptoAPI加密技術 一/二) http://www.vckbase.com/document/listdoc.asp?mclsid=&sclsid=109&page=1
            Crypto API
            學習筆記一//三(另外兩篇baidu下)  http://www.pediy.com/bbshtml/bbs8/pediy8-364.htm

            posted on 2010-08-25 22:01 肥仔 閱讀(894) 評論(0)  編輯 收藏 引用 所屬分類: Windows開發

            无码久久精品国产亚洲Av影片 | 久久强奷乱码老熟女网站| 久久久WWW免费人成精品| 精品无码久久久久久尤物| 久久99精品久久只有精品| 色综合久久精品中文字幕首页| 国产福利电影一区二区三区久久老子无码午夜伦不 | 亚洲成av人片不卡无码久久| 久久福利片| 久久精品麻豆日日躁夜夜躁| 精品国产青草久久久久福利| 久久人妻AV中文字幕| 国产精品久久久99| 久久精品99久久香蕉国产色戒| 久久综合九色欧美综合狠狠| 精品视频久久久久| 人人狠狠综合久久亚洲88| 亚洲国产精品无码久久| 久久er国产精品免费观看8| 久久精品黄AA片一区二区三区| 亚洲伊人久久大香线蕉综合图片| 久久精品国产WWW456C0M| 精品久久777| 影音先锋女人AV鲁色资源网久久| 国产国产成人久久精品| 国产精品一区二区久久精品无码 | 亚洲人成伊人成综合网久久久| 99久久精品免费国产大片| 国产AV影片久久久久久| 午夜精品久久久内射近拍高清| 国产午夜精品久久久久九九电影| 国产欧美久久一区二区| 国产午夜精品久久久久九九电影| 国产成人综合久久精品尤物| 99久久做夜夜爱天天做精品| 国产精品久久成人影院| 精品国产乱码久久久久久人妻| 国产精品久久毛片完整版| 人妻无码精品久久亚瑟影视| 久久精品国产亚洲一区二区| 亚洲国产欧美国产综合久久 |