<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    David.Turing's blog

     

    CryptoAPI第一天

    [轉(zhuǎn)]http://www.chinaitpower.com/A200507/2005-07-27/175804.html

    一:準(zhǔn)備工作
    一般必須包含如下頭
    文件 以及定義
    #include
    #include
    #include
    #define MY_ENCODING_TYPE? (PKCS_7_ASN_ENCODING | X509_ASN_ENCODING)
    ?當(dāng)包含wincrypt.h頭
    文件 時(shí),一般都需要定義#define _WIN32_WINNT 0x(具體的值),否則將得到如下錯(cuò)誤:error C2065: undeclared identifier,不同的操作 系統(tǒng) 不同定義如下:
    Windows Server 2003 family _WIN32_WINNT>=0x0502
    WINVER>=0x0502
    Windows XP _WIN32_WINNT>=0x0501
    WINVER>=0x0501
    Windows 2000 _WIN32_WINNT>=0x0500
    WINVER>=0x0500
    Windows NT 4.0 _WIN32_WINNT>=0x0400
    WINVER>=0x0400
    Windows Me _WIN32_WINDOWS=0x0500
    WINVER>=0x0500
    Windows 98 _WIN32_WINDOWS>=0x0410
    WINVER>=0x0410
    Windows 95 _WIN32_WINDOWS>=0x0400
    WINVER>=0x0400
    Internet Explorer 6.0 _WIN32_IE>=0x0600
    Internet Explorer 5.6 _WIN32_IE>=0x0560
    Internet Explorer 5.01, 5.5 _WIN32_IE>=0x0501
    Internet Explorer 5.0, 5.0a, 5.0b _WIN32_IE>=0x0500
    Internet Explorer 4.01 _WIN32_IE>=0x0401
    Internet Explorer 4.0 _WIN32_IE>=0x0400
    Internet Explorer 3.0, 3.01, 3.02 _WIN32_IE>=0x0300

    二:了解基本知識(shí)
    CryptoAPI的配置信息存儲(chǔ)在注冊(cè)表中,包括如下密鑰:
    HKEY_LOCAL_M(jìn)ACHINE\SOFTWARE\Microsoft \ Cryptography \Defaults
    HKEY_CURRENT_USER\ Software \ Microsoft\ Cryptography \Providers
    ---- CryptoAPI使用兩種密鑰:會(huì)話密鑰與公共/私人密鑰對(duì)。會(huì)話密鑰使用相同的加密和解密密鑰,這種算法較快,但必須保證密鑰的安全傳遞。公共/私人密鑰對(duì)使用一個(gè)公共密鑰和一個(gè)私人密鑰,私人密鑰只有專人才能使用,公共密鑰可以廣泛傳播。如果密鑰對(duì)中的一個(gè)用于加密,另一個(gè)一定用于解密。公共/私人密鑰對(duì)算法很慢,一般只用于加密小批數(shù)據(jù),例如用于加密會(huì)話密鑰。CryptoAPI支持兩種基本的編碼方法:流式編碼和塊編碼。流式編碼在明碼文本的每一位上創(chuàng)建編碼位,速度較快,但安全性較低。塊編碼在一個(gè)完整的塊上(一般為64位)上工作,需要使用填充的方法對(duì)要編碼的數(shù)據(jù)進(jìn)行舍入,以組成多個(gè)完整的塊。這種算法速度較慢,但更安全。

    三:下面進(jìn)入具體的編程?
    一: Creating a Key Container and Generating Keys
    ? 創(chuàng)建一個(gè)密鑰容器,在進(jìn)行加密,解密
    文件 ,并且簽名的時(shí)候,必須需要一個(gè)公/私鑰對(duì),下面我們就來創(chuàng)建默認(rèn)的密鑰容器,要注意的是創(chuàng)建密鑰容器并不會(huì)自動(dòng)產(chǎn)生公/私鑰對(duì).
    ? 下面是我們
    程序 的任務(wù):
    ? 1,假如密鑰容器不存在則創(chuàng)建一個(gè)。
    ? 2,假如簽名密鑰不存在則在密鑰容器里創(chuàng)建一個(gè)。
    ? 3,假如交換密鑰不存在則在密鑰容器里創(chuàng)建一個(gè)。
    ? 4,獲取CSP中的一些參數(shù)
    ? 下面是具體的步驟:
    ? 1,連接缺省的CSP
    BOOL WINAPI CryptAcquireContext(
    ? HCRYPTPROV* phProv,?? //out
    ? LPCTSTR pszContainer, //in
    ? LPCTSTR pszProvider,? //in
    ? DWORD dwProvType,???? //in
    ? DWORD dwFlags???????? //in
    );
    第一個(gè)參數(shù)是返回的CSP句柄,第二個(gè)是密鑰容器的名字,第三個(gè)是A null-terminated string that specifies the name of the CSP to be used.第四個(gè)是指定提供的類型。例如:CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_FULL, 0));
    如果當(dāng)前機(jī)器的未曾設(shè)置過缺省的密鑰容器,因此必須為機(jī)器創(chuàng)建缺省的密鑰容器。
    CryptAcquireContext( &hCryptProv, UserName, NULL, PROV_RSA_FULL, CRYPT_NEWKEYSET)大家有沒有看到,只是最后一個(gè)參數(shù)不同而已,多了一個(gè)CRYPT_NEWKEYSET而已。
    ? 2,取得CSP的參數(shù)
    BOOL WINAPI CryptGetProvParam(
    ? HCRYPTPROV hProv,
    ? DWORD dwParam,
    ? BYTE* pbData,
    ? DWORD* pdwDataLen,
    ? DWORD dwFlags
    );
    第一個(gè)參數(shù)是CSP的句柄,第二個(gè)參數(shù)是需要取得的具體參數(shù)對(duì)象(類型比較多,具體請(qǐng)看MSDN)。
    例子:CryptGetProvParam(hCryptProv, PP_CONTAINER, (BYTE *)szUserName, &dwUserNameLen, 0)
    ? 3,函數(shù)返回所獲取密鑰類型的句柄(0表失敗,非0表成功)
    BOOL WINAPI CryptGetUserKey(
    ? HCRYPTPROV hProv,
    ? DWORD dwKeySpec,
    ? HCRYPTKEY* phUserKey
    );
    ? 參數(shù)比較簡(jiǎn)單,只談?wù)劦诙螀?shù),它可以是AT_KEYEXCHANGE(交換密鑰) or AT_SIGNATURE(簽名密鑰),例如:
    CryptGetUserKey(hCryptProv,AT_KEYEXCHANGE,&hKey)
    ? 4,產(chǎn)生一個(gè)隨機(jī)的交換密鑰或者公/私鑰對(duì)
    BOOL WINAPI CryptGenKey(
    ? HCRYPTPROV hProv,
    ? ALG_ID Algid,
    ? DWORD dwFlags,
    ? HCRYPTKEY* phKey
    );
    ALG_ID 表明產(chǎn)生私鑰所使用的算法。有如下參數(shù):
    微軟 提供的基本算法
    CALG_MD2,CALG_MD5,CALG_SHA,CALG_SHA1,CALG_MAC,CALG_HMAC,CALG_SSL3_SHAMD5,CALG_MD2,CALG_MD2
    CALG_RSA_SIGN,CALG_RSA_KEYX,CALG_RC2,CALG_RC4,CALG_DES
    微軟 提供的增強(qiáng)型算法:
    CALG_MD2,CALG_MD5,CALG_SHA,CALG_SHA1
    CALG_MAC,CALG_HMAC ,CALG_SSL3_SHAMD5,CALG_RSA_SIGN,CALG_RSA_KEYX,CALG_RC2,CALG_RC4,CALG_DES,CALG_3DES_112,CALG_3DES
    使用DH的CSP有如下兩個(gè)參數(shù),CALG_DH_EPHEM,CALG_DH_SF
    使用公開密鑰算法:AT_KEYEXCHANGE,AT_SIGNATURE
    dwFlags,,表示密鑰使用的長(zhǎng)度,參數(shù)可以為0,采用默認(rèn)的密鑰長(zhǎng)度?;蛘呤沁M(jìn)行如下幾個(gè)參數(shù)的或:
    CRYPT_ARCHIVABLE:表示在句柄在關(guān)閉之前都能夠被導(dǎo)出
    CRYPT_CREATE_SALT:表示密鑰按照一個(gè)salt value來隨機(jī)產(chǎn)生。
    CRYPT_EXPORTABLE:表示密鑰可以從CSP中導(dǎo)出到BLOB,因?yàn)闀?huì)話密鑰產(chǎn)生是必須可導(dǎo)出的,所以必須設(shè)置
    CRYPT_NO_SALT:表示沒有SALT VALUE獲取allocated for a forty-bit symmetric key
    CRYPT_PREGEN:表示在DH或者DSS密鑰產(chǎn)生必須有個(gè)初始化。
    例如:CryptGenKey(hCryptProv,AT_KEYEXCHANGE,0,&hKey)
    ? 5,釋放CSP句柄
    BOOL WINAPI CryptReleaseContext(
    ? HCRYPTPROV hProv,
    ? DWORD dwFlags //保留字,現(xiàn)在必須為0
    );
    ? 6,為CSP增加一個(gè)reference count(用來跟蹤C(jī)OM對(duì)象的整數(shù)值,當(dāng)對(duì)象創(chuàng)建,值為1。每次對(duì)對(duì)象的操作都將增加,而對(duì)對(duì)象的關(guān)閉將減少,當(dāng)值為0是,對(duì)象釋放,所以與對(duì)象相關(guān)操作將無效)
    BOOL WINAPI CryptContextAddRef(
    ? HCRYPTPROV hProv,
    ? DWORD* pdwReserved,? //保留字,必須為NULL
    ? DWORD dwFlags??????? //保留字,必須為0
    );

    ? 二:Deriving a Session Key from a Password
    ? 1,連接CSP
    ? 2,使用CryptCreateHash產(chǎn)生一個(gè)空的HASH對(duì)象
    ? 3,對(duì)密碼進(jìn)行HASH處理
    ? 4,釋放HASH以及密碼對(duì)象
    ? 5,釋放CSP
    ? 下面是具體的步驟:
    ? 1,CryptCreateHash初始化一個(gè)HASH對(duì)象
    BOOL WINAPI CryptCreateHash(
    ? HCRYPTPROV hProv,? //in
    ? ALG_ID Algid,????? //in
    ? HCRYPTKEY hKey,??? //in
    ? DWORD dwFlags,???? //in保留字,必須為0
    ? HCRYPTHASH* phHash //out
    );
    第二個(gè)參數(shù)是指定HASH算法,有CALG_HMAC,CALG_MAC,CALG_MD2,CALG_MD5,CALG_SHA,CALG_SHA1,CALG_SSL3_SHAMD5。第三個(gè)參數(shù)對(duì)于那些keyed hash,例如HMAC,MAC算法。但是nonkeyed算法,必須設(shè)置為0。
    ? 2,CryptHashData對(duì)數(shù)據(jù)使用HASH
    BOOL WINAPI CryptHashData(
    ? HCRYPTHASH hHash,? //in,HASH對(duì)象句柄
    ? BYTE* pbData,????? //in,待HASH的數(shù)據(jù)
    ? DWORD dwDataLen,?? //in,待HASH數(shù)據(jù)的長(zhǎng)度,當(dāng)dwFlags為CRYPT_USERDATA為0時(shí),必須為0
    ? DWORD dwFlags????? //in,一般為0,或者為CRYPT_USERDATA(用在用戶進(jìn)入
    系統(tǒng) 時(shí)需要輸入PIN)
    );
    ? 3,CryptDeriveKey從某一數(shù)據(jù)產(chǎn)生會(huì)話密鑰,他有點(diǎn)類似CryptGenKey,但是他產(chǎn)生的會(huì)話密鑰來自固定數(shù)據(jù),而CryptGenKey是隨機(jī)產(chǎn)生的。并且不能產(chǎn)生公/私鑰對(duì)
    BOOL WINAPI CryptDeriveKey(
    ? HCRYPTPROV hProv,????? //in,CSP句柄
    ? ALG_ID Algid,????????? //in,指定的算法,類似CryptGenKey
    ? HCRYPTHASH hBaseData,? //in,HASH對(duì)象的句柄
    ? DWORD dwFlags,???????? //in,指定產(chǎn)生密鑰的類型
    ? HCRYPTKEY* phKey?????? //in,out產(chǎn)生的密鑰句柄地址
    );
    例如:CryptDeriveKey(hCryptProv, CALG_RC2, hHash, CRYPT_EXPORTABLE, &hKey)
    ? 4,CryptDestroyHash(hHash);
    ? 5, CryptDestroyKey(hKey);
    ? 6, 在這里發(fā)現(xiàn)一個(gè)不錯(cuò)的函數(shù),就是那種提示輸入密碼的命令行(屏幕只會(huì)出現(xiàn)***)
    ? void GetConsoleInput(char* strInput, int intMaxChars)
    {
    ?char ch;
    ?char minChar = ' ';
    ?minChar++;
    ?ch = getch();
    ?while (ch != '\r')
    ?{
    ? if (ch == '\b' && strlen(strInput) > 0)
    ? {
    ?? strInput[strlen(strInput)-1]?? = '\0';
    ?? printf("\b \b");
    ? }
    ? else if (ch >= minChar && strlen(strInput) < intMaxChars)
    ? {
    ?? strInput[strlen(strInput)+1] = '\0';
    ?? strInput[strlen(strInput)]?? = ch;
    ?? putch('*');
    ? }
    ? ch = getch();
    ?}
    ?putch('\n');
    }

    ? 三:Duplicating,setting and getting Session key
    ? 1,連接CSP
    ? 2,使用CryptGenKey產(chǎn)生一個(gè)會(huì)話密鑰
    ? 3,CryptDuplicateKey復(fù)制會(huì)話密鑰
    ? 4,CryptSetKeyParam改變密鑰產(chǎn)生的過程
    ? 5,CryptGenRandom產(chǎn)生隨機(jī)數(shù)
    具體過程。
    1,CryptDuplicateKe復(fù)制會(huì)話密鑰
    BOOL WINAPI CryptDuplicateKey(
    ? HCRYPTKEY hKey,????? //in 會(huì)話密鑰句柄
    ? DWORD* pdwReserved,? //in 保留字,必須為NULL
    ? DWORD dwFlags,?????? //in 保留字,必須為0
    ? HCRYPTKEY* phKey???? //out 新的會(huì)話密鑰
    );
    2,CryptSetKeyParam定制會(huì)話密鑰的參數(shù)
    BOOL WINAPI CryptSetKeyParam(
    ? HCRYPTKEY hKey,
    ? DWORD dwParam,? //in 很多,具體請(qǐng)看MSDN
    ? BYTE* pbData,
    ? DWORD dwFlags? //in? 只有在dwParam=KP_ALGID才被使用
    );
    例如CryptSetKeyParam(hOriginalKey, KP_MODE, (BYTE*)&dwMode, 0)(dwMode = CRYPT_MODE_ECB)
    3,CryptGenRandom為空間產(chǎn)生隨機(jī)字節(jié)
    BOOL WINAPI CryptGenRandom(
    ? HCRYPTPROV hProv,
    ? DWORD dwLen,??? //需要產(chǎn)生的隨機(jī)比特?cái)?shù)
    ? BYTE* pbBuffer? //需要返回?cái)?shù)據(jù)的空間,這個(gè)pbBuffer可以等于CryptSetKeyParam的pbData
    );
    例如:CryptGenRandom(hCryptProv, 8, pbData)
    4,CryptGetKeyParam獲取密鑰的一些參數(shù)
    BOOL WINAPI CryptGetKeyParam(
    ? HCRYPTKEY hKey,
    ? DWORD dwParam,???? //in,參數(shù)眾多
    ? BYTE* pbData,????? //out,獲取BYTE數(shù)據(jù)的指針
    ? DWORD* pdwDataLen, //out,獲取BYTE數(shù)據(jù)的長(zhǎng)度
    ? DWORD dwFlags????? //關(guān)鍵字,必須為0
    );
    例如:CryptGetKeyParam(hKey, KP_IV, pbData, &dwCount, 0)


    ? 四:Exporting a Session Key
    ? 1,連接CSP
    ? 2,CryptGetUserKey獲取公/私鑰對(duì)和交換密鑰,公私鑰用來簽名,而交換密鑰用來導(dǎo)出會(huì)話密鑰
    ? 3,CryptGenKey產(chǎn)生會(huì)話密鑰
    ? 4,CryptExportKey創(chuàng)建簡(jiǎn)單包含有會(huì)話密鑰的key BLOB
    ? 5,釋放處理:
    ? 具體過程:
    1,CryptExportKey函數(shù)導(dǎo)出密鑰
    BOOL WINAPI CryptExportKey(
    ? HCRYPTKEY hKey,???? //需要導(dǎo)出的密鑰句柄
    ? HCRYPTKEY hExpKey,? //將待導(dǎo)出密鑰用交換密鑰進(jìn)行加密,假如是公開的BLOG當(dāng)然就設(shè)置為0
    ? DWORD dwBlobType,?? //指定導(dǎo)出的密鑰BLOB類型。六個(gè)參數(shù)見MSDN
    ? DWORD dwFlags,????? //CRYPT_DESTROYKEY,CRYPT_SSL2_FALLBACK,CRYPT_OAEP
    ? BYTE* pbData,?????? //導(dǎo)出的數(shù)據(jù)指針,以后就可以將這個(gè)數(shù)據(jù)寫如磁盤或者別的任務(wù)。
    ? DWORD* pdwDataLen?? //導(dǎo)出的數(shù)據(jù)長(zhǎng)度
    );
    例如:CryptExportKey(hKey, hXchgKey, SIMPLEBLOB, 0, pbKeyBlob, &dwBlobLen)
    2,CryptImportKey將密鑰從BLOB轉(zhuǎn)換到CSP中
    BOOL WINAPI CryptImportKey(
    ? HCRYPTPROV hProv,? //CSP句柄
    ? BYTE* pbData,????? //待轉(zhuǎn)換的BLOB數(shù)據(jù)
    ? DWORD dwDataLen,?? //待轉(zhuǎn)換的數(shù)據(jù)長(zhǎng)度
    ? HCRYPTKEY hPubKey, //對(duì)BLOB解密的公鑰,譬如上面是用交換密鑰密鑰加密的,就用交換密鑰解密
    ? DWORD dwFlags,???? //目前還只應(yīng)用在當(dāng)一對(duì)公/私鑰從PRIVATEKEYBLOB中加入CSP中這種情況。
    ? HCRYPTKEY* phKey?? //out導(dǎo)入的密鑰
    );
    例如:CryptImportKey(hProv,pbKeyBlob,dwBlobLen,0,0,&hPubKey)


    ? 五:Encoding and Decoding Messages
    ? 編碼的處理過程
    ? 1,將待編碼的數(shù)據(jù)轉(zhuǎn)化為合適的格式,使用
    ? 2,調(diào)用CryptMsgOpenToEncode,passing the necessary argument;
    ? 3, 調(diào)用CryptMsgUpdate函數(shù)多次,最后一次調(diào)用時(shí),將final參數(shù)設(shè)置為true
    ? 4, 調(diào)用CryptMsgGetParam來獲取一個(gè)需要得到的參數(shù)。
    ? 5, 調(diào)用CryptMsgClose來關(guān)閉消息
    ? 解碼的處理過程
    ? 1,檢查申請(qǐng)的放編碼后數(shù)據(jù)的空間,利用函數(shù)CryptMsgCalculateEncodedLength.
    ? 2,調(diào)用函數(shù)CryptMsgOpenToDecode,passing the necessary argument;
    ? 3,調(diào)用CryptMsgUpdate一次,這將導(dǎo)致合適的動(dòng)作去處理信息,以來于信息的格式
    ? 4,一些額外的處理,例如額外的解密或者是驗(yàn)證,調(diào)用CryptMsgControl,
    ? 5,調(diào)用CryptMsgGetParam來獲取需要得到的參數(shù)
    ? 6,調(diào)用CryptMsgClose來關(guān)閉消息
    ? 具體的函數(shù)介紹:
    ? 1,CryptMsgCalculateEncodedLength計(jì)算所需要的存儲(chǔ)編碼的最大空間值
    DWORD WINAPI CryptMsgCalculateEncodedLength(
    ? DWORD dwMsgEncodingType,//指定編碼類型。一般為X509_ASN_ENCODING|PKCS_7_ASN_ENCODING
    ? DWORD dwFlags,
    ? DWORD dwMsgType,
    ? const void* pvMsgEncodeInfo, //in 指向待編碼的數(shù)據(jù),數(shù)據(jù)類型依賴于dwMsgType
    ? LPSTR pszInnerContentObjID,
    ? DWORD cbData???????????????? //in 比特?cái)?shù)的容量
    );
    第二個(gè)參數(shù):CMSG_BARE_CONTENT_FLAG,CMSG_DETACHED_FLAG,CMSG_CONTENTS_OCTETS_FLAG,CMSG_CMS_ENCAPSULATED_CONTENT_FLAG
    第三個(gè)參數(shù):CMSG_DATA,CMSG_SIGNED,CMSG_ENVELOPED,CMSG_SIGNED_AND_ENVELOPED,CMSG_HASHED,CMSG_ENCRYPTED
    第五個(gè)參數(shù):szOID_RSA_data,szOID_RSA_signedData,szOID_RSA_envelopedData,szOID_RSA_signEnvData,szOID_RSA,digestedData ,
    szOID_RSA_encryptedData,SPC_INDIRECT_DATA_OBJID,NULL
    返回值:返回需要的一個(gè)加密信息所需要的長(zhǎng)度
    ? 2,CryptMsgOpenToEncode打開一個(gè)消息以便進(jìn)行編碼,返回打開消息的句柄
    ? HCRYPTMSG WINAPI CryptMsgOpenToEncode(
    ? DWORD dwMsgEncodingType,????? //指定編碼類型。一般為X509_ASN_ENCODING|PKCS_7_ASN_ENCODING
    ? DWORD dwFlags,???????????????
    ? DWORD dwMsgType,?????????????
    ? const void* pvMsgEncodeInfo,
    ? LPSTR pszInnerContentObjID,??? //和CryptMsgCalculateEncodedLength一樣
    ? PCMSG_STREAM_INFO pStreamInfo //當(dāng)流沒被使用時(shí),該參數(shù)為NULL
    );
    第二個(gè)參數(shù):CMSG_BARE_CONTENT_FLAG,CMSG_DETACHED_FLAG,CMSG_CONTENTS_OCTETS_FLAG,CMSG_CMS_ENCAPSULATED_CONTENT_FLAG,
    CMSG_CRYPT_RELEASE_CONTEXT_FLAG
    第三個(gè)參數(shù):
    CMSG_DATA(Not used),CMSG_SIGNED,CMSG_SIGNED_ENCODE_INFO,CMSG_ENVELOPED,CMSG_ENVELOPED_ENCODE_INFO
    CMSG_SIGNED_AND_ENVELOPED(Not currently implemented),CMSG_HASHED
    ? 3,CryptMsgOpenToDecode打開一個(gè)消息以便進(jìn)行解碼,返回打開消息的句柄
    ? CRYPTMSG WINAPI CryptMsgOpenToDecode(
    ? DWORD dwMsgEncodingType,???? //指定編碼類型。一般為X509_ASN_ENCODING|PKCS_7_ASN_ENCODING
    ? DWORD dwFlags,?? //CMSG_DETACHED_FLAG,CMSG_CRYPT_RELEASE_CONTEXT_FLAG
    ? DWORD dwMsgType, //CMSG_DATA,CMSG_ENVELOPED,CMSG_HASHED,CMSG_SIGNED,CMSG_SIGNED_AND_ENVELOPED
    ? HCRYPTPROV hCryptProv,??? //指定使用HASHING的句柄,一般設(shè)置為0
    ? PCERT_INFO pRecipientInfo,//保留字,必須為NULL
    ? PCMSG_STREAM_INFO pStreamInfo//假如流沒被使用,必須為NULL
    );
    ? 4,CryptMsgUpdate增加內(nèi)容到加密信息中
    BOOL WINAPI CryptMsgUpdate(
    ? HCRYPTMSG hCryptMsg, //待更新的加密信息句柄
    ? const BYTE* pbData,? //待編碼/解碼的數(shù)據(jù)
    ? DWORD cbData,??????? // pbData 的數(shù)據(jù)長(zhǎng)度
    ? BOOL fFinal?????????
    );
    第四個(gè)參數(shù):當(dāng)CMSG_DETACHED_FLAG沒有設(shè)置,并且信息由CryptMsgOpenToDecode或CryptMsgOpenToEncode打開,那么fFinal被設(shè)置為TRUE,并且CryptMsgUpdate只被調(diào)用一次。當(dāng)CMSG_DETACHED_FLAG被設(shè)置,并且信息由 CryptMsgOpenToEncode打開,那么僅在最后一次調(diào)用CryptMsgUpdate才被設(shè)置為TRUE。當(dāng)CMSG_DETACHED_FLAG被設(shè)置,并且信息由CryptMsgOpenToDecode打開,那么僅在信息頭單獨(dú)被處理時(shí)CryptMsgUpdate才被設(shè)置為TRUE。
    ? 5,CryptMsgGetParam在數(shù)據(jù)編碼/解碼后獲取參數(shù)
    ? BOOL WINAPI CryptMsgGetParam(
    ? HCRYPTMSG hCryptMsg,? //in 信息句柄
    ? DWORD dwParamType,?? //in 參數(shù)眾多,參見MSDN
    ? DWORD dwIndex,?????? //in 可適用的返回參數(shù)句柄,假如參數(shù)沒有被獲取,則被忽略或則為0
    ? void* pvData,??????? //out 獲取的數(shù)據(jù)指針
    ? DWORD* pcbData????? //in,out數(shù)據(jù)長(zhǎng)度
    );
    ?? 6,CryptMsgClose關(guān)閉信息句柄
    BOOL WINAPI CryptMsgClose(
    ? HCRYPTMSG hCryptMsg
    );
    具體的例子:
    cbEncodedBlob = CryptMsgCalculateEncodedLength(
    ???????????? MY_ENCODING_TYPE,?????? // Message encoding type
    ???????????? 0,????????????????????? // Flags
    ???????????? CMSG_DATA,????????????? // Message type
    ???????????? NULL,?????????????????? // Pointer to structure
    ???????????? NULL,?????????????????? // Inner content object ID
    ???????????? cbContent))???????????? // Size of content
    hMsg = CryptMsgOpenToEncode(
    ????????? MY_ENCODING_TYPE,??????? // Encoding type
    ????????? 0,?????????????????????? // Flags
    ????????? CMSG_DATA,?????????????? // Message type
    ????????? NULL,??????????????????? // Pointer to structure
    ????????? NULL,??????????????????? // Inner content object ID
    ????????? NULL))?????????????????? // Stream information (not used)
    CryptMsgUpdate(
    ??????? hMsg,???????? // Handle to the message
    ??????? pbContent,??? // Pointer to the content
    ??????? cbContent,??? // Size of the content
    ??????? TRUE))??????? // Last call
    {
    CryptMsgGetParam(
    ?????????????? hMsg,????????????????????? // Handle to the message
    ?????????????? CMSG_BARE_CONTENT_PARAM,?? // Parameter type
    ?????????????? 0,???????????????????????? // Index
    ?????????????? pbEncodedBlob,???????????? // Pointer to the BLOB
    ?????????????? &cbEncodedBlob))?????????? // Size of the BLOB
    CryptMsgClose(hMsg);
    hMsg = CryptMsgOpenToDecode(
    ?????????????? MY_ENCODING_TYPE,????? // Encoding type.
    ?????????????? 0,???????????????????? // Flags.
    ?????????????? CMSG_DATA,???????????? // Look for a data message.
    ?????????????? NULL,????????????????? // Cryptographic provider.
    ?????????????? NULL,????????????????? // Recipient information.
    ?????????????? NULL))???????????????? // Stream information.

    posted on 2006-07-05 23:18 david.turing 閱讀(3457) 評(píng)論(1)  編輯  收藏 所屬分類: CryptoAPI

    評(píng)論

    # re: CryptoAPI第一天 2008-03-26 16:39 haityang

    請(qǐng)教您一個(gè)問題,假如我現(xiàn)在有一個(gè)pkcs#7 envelope,假設(shè)它是由三個(gè)證書加密的,但我沒有任何一個(gè)證書的私鑰,現(xiàn)在我想從這個(gè)信封中刪除一個(gè)證書.應(yīng)該怎么實(shí)現(xiàn)?  回復(fù)  更多評(píng)論   


    只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。


    網(wǎng)站導(dǎo)航:
     

    導(dǎo)航

    統(tǒng)計(jì)

    常用鏈接

    留言簿(110)

    我參與的團(tuán)隊(duì)

    隨筆分類(126)

    隨筆檔案(155)

    文章分類(9)

    文章檔案(19)

    相冊(cè)

    搜索

    積分與排名

    最新隨筆

    最新評(píng)論

    閱讀排行榜

    評(píng)論排行榜

    主站蜘蛛池模板: 亚洲色欲或者高潮影院| 亚洲精品色午夜无码专区日韩| 亚洲av女电影网| 中文字幕无码免费久久| 国产亚洲一区二区精品| 男人天堂免费视频| 亚洲avav天堂av在线不卡| 亚洲a一级免费视频| 91亚洲国产在人线播放午夜 | 美女尿口扒开图片免费| 免费一级毛片在线播放| 国产免费内射又粗又爽密桃视频| 亚洲亚洲人成综合网络| 午夜免费福利片观看| 亚洲熟妇无码久久精品| 我想看一级毛片免费的| 理论亚洲区美一区二区三区| 亚洲国产日韩成人综合天堂| 在线观看人成视频免费无遮挡| 亚洲欧洲第一a在线观看| 99在线精品免费视频九九视 | 黄色网址大全免费| 国产AV无码专区亚洲AWWW| 久久久久久免费一区二区三区| 久久精品国产精品亚洲艾| 美女视频黄免费亚洲| 色噜噜的亚洲男人的天堂| 亚洲色大成网站www永久一区 | 精品剧情v国产在免费线观看| 国产亚洲精品免费| 亚洲av伊人久久综合密臀性色| 中国人xxxxx69免费视频| 久久精品国产亚洲AV未满十八| 国产自偷亚洲精品页65页| 59pao成国产成视频永久免费| 亚洲avav天堂av在线网毛片| 国产AV无码专区亚洲AV男同| 午夜国产精品免费观看| 特级毛片A级毛片免费播放| 337p日本欧洲亚洲大胆色噜噜| 日本不卡免费新一二三区|