• <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 肥仔 閱讀(901) 評論(0)  編輯 收藏 引用 所屬分類: Windows開發

            久久er国产精品免费观看8| 一本久久综合亚洲鲁鲁五月天亚洲欧美一区二区 | 久久久www免费人成精品| 亚洲欧美伊人久久综合一区二区| 欧美午夜精品久久久久免费视| 久久A级毛片免费观看| 国产精品va久久久久久久| 久久99热这里只频精品6| 国内精品久久久久伊人av| 亚洲欧美精品一区久久中文字幕| 亚洲国产精品久久久天堂| 久久精品国产亚洲Aⅴ香蕉| 影音先锋女人AV鲁色资源网久久| 伊人久久精品线影院| 久久午夜福利无码1000合集| 国产精品久久久久一区二区三区 | 久久精品国产亚洲AV影院| 色婷婷久久综合中文久久蜜桃av | 久久久久亚洲AV片无码下载蜜桃| 熟妇人妻久久中文字幕| 久久久久久国产精品无码下载| 久久精品午夜一区二区福利| 国产精品久久一区二区三区| 久久久国产精华液| 2021久久精品免费观看| 久久这里只有精品视频99| 国产ww久久久久久久久久| 九九99精品久久久久久| 久久久久无码精品国产不卡| 免费精品久久天干天干| 久久亚洲精品国产精品婷婷| 色青青草原桃花久久综合| 久久精品免费网站网| 欧美久久久久久午夜精品| 国产精品无码久久久久| 国产叼嘿久久精品久久| 久久精品成人免费观看97| 久久久久99精品成人片| 国产成人综合久久精品红| 久久精品一区二区三区AV| 性高湖久久久久久久久|