<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第一天

    [轉]http://www.chinaitpower.com/A200507/2005-07-27/175804.html

    一:準備工作
    一般必須包含如下頭
    文件 以及定義
    #include
    #include
    #include
    #define MY_ENCODING_TYPE? (PKCS_7_ASN_ENCODING | X509_ASN_ENCODING)
    ?當包含wincrypt.h頭
    文件 時,一般都需要定義#define _WIN32_WINNT 0x(具體的值),否則將得到如下錯誤:error C2065: undeclared identifier,不同的操作 系統 不同定義如下:
    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

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

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

    ? 二:Deriving a Session Key from a Password
    ? 1,連接CSP
    ? 2,使用CryptCreateHash產生一個空的HASH對象
    ? 3,對密碼進行HASH處理
    ? 4,釋放HASH以及密碼對象
    ? 5,釋放CSP
    ? 下面是具體的步驟:
    ? 1,CryptCreateHash初始化一個HASH對象
    BOOL WINAPI CryptCreateHash(
    ? HCRYPTPROV hProv,? //in
    ? ALG_ID Algid,????? //in
    ? HCRYPTKEY hKey,??? //in
    ? DWORD dwFlags,???? //in保留字,必須為0
    ? HCRYPTHASH* phHash //out
    );
    第二個參數是指定HASH算法,有CALG_HMAC,CALG_MAC,CALG_MD2,CALG_MD5,CALG_SHA,CALG_SHA1,CALG_SSL3_SHAMD5。第三個參數對于那些keyed hash,例如HMAC,MAC算法。但是nonkeyed算法,必須設置為0。
    ? 2,CryptHashData對數據使用HASH
    BOOL WINAPI CryptHashData(
    ? HCRYPTHASH hHash,? //in,HASH對象句柄
    ? BYTE* pbData,????? //in,待HASH的數據
    ? DWORD dwDataLen,?? //in,待HASH數據的長度,當dwFlags為CRYPT_USERDATA為0時,必須為0
    ? DWORD dwFlags????? //in,一般為0,或者為CRYPT_USERDATA(用在用戶進入
    系統 時需要輸入PIN)
    );
    ? 3,CryptDeriveKey從某一數據產生會話密鑰,他有點類似CryptGenKey,但是他產生的會話密鑰來自固定數據,而CryptGenKey是隨機產生的。并且不能產生公/私鑰對
    BOOL WINAPI CryptDeriveKey(
    ? HCRYPTPROV hProv,????? //in,CSP句柄
    ? ALG_ID Algid,????????? //in,指定的算法,類似CryptGenKey
    ? HCRYPTHASH hBaseData,? //in,HASH對象的句柄
    ? DWORD dwFlags,???????? //in,指定產生密鑰的類型
    ? HCRYPTKEY* phKey?????? //in,out產生的密鑰句柄地址
    );
    例如:CryptDeriveKey(hCryptProv, CALG_RC2, hHash, CRYPT_EXPORTABLE, &hKey)
    ? 4,CryptDestroyHash(hHash);
    ? 5, CryptDestroyKey(hKey);
    ? 6, 在這里發現一個不錯的函數,就是那種提示輸入密碼的命令行(屏幕只會出現***)
    ? 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產生一個會話密鑰
    ? 3,CryptDuplicateKey復制會話密鑰
    ? 4,CryptSetKeyParam改變密鑰產生的過程
    ? 5,CryptGenRandom產生隨機數
    具體過程。
    1,CryptDuplicateKe復制會話密鑰
    BOOL WINAPI CryptDuplicateKey(
    ? HCRYPTKEY hKey,????? //in 會話密鑰句柄
    ? DWORD* pdwReserved,? //in 保留字,必須為NULL
    ? DWORD dwFlags,?????? //in 保留字,必須為0
    ? HCRYPTKEY* phKey???? //out 新的會話密鑰
    );
    2,CryptSetKeyParam定制會話密鑰的參數
    BOOL WINAPI CryptSetKeyParam(
    ? HCRYPTKEY hKey,
    ? DWORD dwParam,? //in 很多,具體請看MSDN
    ? BYTE* pbData,
    ? DWORD dwFlags? //in? 只有在dwParam=KP_ALGID才被使用
    );
    例如CryptSetKeyParam(hOriginalKey, KP_MODE, (BYTE*)&dwMode, 0)(dwMode = CRYPT_MODE_ECB)
    3,CryptGenRandom為空間產生隨機字節
    BOOL WINAPI CryptGenRandom(
    ? HCRYPTPROV hProv,
    ? DWORD dwLen,??? //需要產生的隨機比特數
    ? BYTE* pbBuffer? //需要返回數據的空間,這個pbBuffer可以等于CryptSetKeyParam的pbData
    );
    例如:CryptGenRandom(hCryptProv, 8, pbData)
    4,CryptGetKeyParam獲取密鑰的一些參數
    BOOL WINAPI CryptGetKeyParam(
    ? HCRYPTKEY hKey,
    ? DWORD dwParam,???? //in,參數眾多
    ? BYTE* pbData,????? //out,獲取BYTE數據的指針
    ? DWORD* pdwDataLen, //out,獲取BYTE數據的長度
    ? DWORD dwFlags????? //關鍵字,必須為0
    );
    例如:CryptGetKeyParam(hKey, KP_IV, pbData, &dwCount, 0)


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


    ? 五:Encoding and Decoding Messages
    ? 編碼的處理過程
    ? 1,將待編碼的數據轉化為合適的格式,使用
    ? 2,調用CryptMsgOpenToEncode,passing the necessary argument;
    ? 3, 調用CryptMsgUpdate函數多次,最后一次調用時,將final參數設置為true
    ? 4, 調用CryptMsgGetParam來獲取一個需要得到的參數。
    ? 5, 調用CryptMsgClose來關閉消息
    ? 解碼的處理過程
    ? 1,檢查申請的放編碼后數據的空間,利用函數CryptMsgCalculateEncodedLength.
    ? 2,調用函數CryptMsgOpenToDecode,passing the necessary argument;
    ? 3,調用CryptMsgUpdate一次,這將導致合適的動作去處理信息,以來于信息的格式
    ? 4,一些額外的處理,例如額外的解密或者是驗證,調用CryptMsgControl,
    ? 5,調用CryptMsgGetParam來獲取需要得到的參數
    ? 6,調用CryptMsgClose來關閉消息
    ? 具體的函數介紹:
    ? 1,CryptMsgCalculateEncodedLength計算所需要的存儲編碼的最大空間值
    DWORD WINAPI CryptMsgCalculateEncodedLength(
    ? DWORD dwMsgEncodingType,//指定編碼類型。一般為X509_ASN_ENCODING|PKCS_7_ASN_ENCODING
    ? DWORD dwFlags,
    ? DWORD dwMsgType,
    ? const void* pvMsgEncodeInfo, //in 指向待編碼的數據,數據類型依賴于dwMsgType
    ? LPSTR pszInnerContentObjID,
    ? DWORD cbData???????????????? //in 比特數的容量
    );
    第二個參數:CMSG_BARE_CONTENT_FLAG,CMSG_DETACHED_FLAG,CMSG_CONTENTS_OCTETS_FLAG,CMSG_CMS_ENCAPSULATED_CONTENT_FLAG
    第三個參數:CMSG_DATA,CMSG_SIGNED,CMSG_ENVELOPED,CMSG_SIGNED_AND_ENVELOPED,CMSG_HASHED,CMSG_ENCRYPTED
    第五個參數:szOID_RSA_data,szOID_RSA_signedData,szOID_RSA_envelopedData,szOID_RSA_signEnvData,szOID_RSA,digestedData ,
    szOID_RSA_encryptedData,SPC_INDIRECT_DATA_OBJID,NULL
    返回值:返回需要的一個加密信息所需要的長度
    ? 2,CryptMsgOpenToEncode打開一個消息以便進行編碼,返回打開消息的句柄
    ? 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 //當流沒被使用時,該參數為NULL
    );
    第二個參數:CMSG_BARE_CONTENT_FLAG,CMSG_DETACHED_FLAG,CMSG_CONTENTS_OCTETS_FLAG,CMSG_CMS_ENCAPSULATED_CONTENT_FLAG,
    CMSG_CRYPT_RELEASE_CONTEXT_FLAG
    第三個參數:
    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打開一個消息以便進行解碼,返回打開消息的句柄
    ? 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的句柄,一般設置為0
    ? PCERT_INFO pRecipientInfo,//保留字,必須為NULL
    ? PCMSG_STREAM_INFO pStreamInfo//假如流沒被使用,必須為NULL
    );
    ? 4,CryptMsgUpdate增加內容到加密信息中
    BOOL WINAPI CryptMsgUpdate(
    ? HCRYPTMSG hCryptMsg, //待更新的加密信息句柄
    ? const BYTE* pbData,? //待編碼/解碼的數據
    ? DWORD cbData,??????? // pbData 的數據長度
    ? BOOL fFinal?????????
    );
    第四個參數:當CMSG_DETACHED_FLAG沒有設置,并且信息由CryptMsgOpenToDecode或CryptMsgOpenToEncode打開,那么fFinal被設置為TRUE,并且CryptMsgUpdate只被調用一次。當CMSG_DETACHED_FLAG被設置,并且信息由 CryptMsgOpenToEncode打開,那么僅在最后一次調用CryptMsgUpdate才被設置為TRUE。當CMSG_DETACHED_FLAG被設置,并且信息由CryptMsgOpenToDecode打開,那么僅在信息頭單獨被處理時CryptMsgUpdate才被設置為TRUE。
    ? 5,CryptMsgGetParam在數據編碼/解碼后獲取參數
    ? BOOL WINAPI CryptMsgGetParam(
    ? HCRYPTMSG hCryptMsg,? //in 信息句柄
    ? DWORD dwParamType,?? //in 參數眾多,參見MSDN
    ? DWORD dwIndex,?????? //in 可適用的返回參數句柄,假如參數沒有被獲取,則被忽略或則為0
    ? void* pvData,??????? //out 獲取的數據指針
    ? DWORD* pcbData????? //in,out數據長度
    );
    ?? 6,CryptMsgClose關閉信息句柄
    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) 評論(1)  編輯  收藏 所屬分類: CryptoAPI

    評論

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

    請教您一個問題,假如我現在有一個pkcs#7 envelope,假設它是由三個證書加密的,但我沒有任何一個證書的私鑰,現在我想從這個信封中刪除一個證書.應該怎么實現?  回復  更多評論   


    只有注冊用戶登錄后才能發表評論。


    網站導航:
     

    導航

    統計

    常用鏈接

    留言簿(110)

    我參與的團隊

    隨筆分類(126)

    隨筆檔案(155)

    文章分類(9)

    文章檔案(19)

    相冊

    搜索

    積分與排名

    最新隨筆

    最新評論

    閱讀排行榜

    評論排行榜

    主站蜘蛛池模板: 在线亚洲午夜片AV大片| 四虎国产精品免费久久| 福利片免费一区二区三区| 亚洲视频在线观看网站| 最新精品亚洲成a人在线观看| 国内自产少妇自拍区免费| a拍拍男女免费看全片| 日本免费在线中文字幕| 成年免费大片黄在线观看com| 亚洲欧美日韩一区二区三区| 亚洲伦理一二三四| 亚洲色图在线播放| 亚洲开心婷婷中文字幕| 亚洲伊人久久综合影院| 四虎永久免费影院| 在线视频免费国产成人| 午夜成人免费视频| 蜜桃视频在线观看免费网址入口| 99久久久国产精品免费牛牛| 久久国产精品国产自线拍免费 | 免费精品国偷自产在线在线| 小日子的在线观看免费| 免费国产在线视频| 在线看片免费人成视频福利| 你懂的免费在线观看| 中国好声音第二季免费播放| 国产精品综合专区中文字幕免费播放 | 亚洲一区二区三区亚瑟 | 最近中文字幕无免费| 久久免费公开视频| 桃子视频在线观看高清免费视频| 两性色午夜免费视频| a级毛片毛片免费观看久潮喷 | 中文字幕日韩亚洲| 中文亚洲AV片在线观看不卡 | 成全视频免费观看在线看| 99免费精品视频| 一级毛片在线免费观看| 精品熟女少妇av免费久久| h视频在线免费看| 手机在线免费视频|