Làm thế nào để xuất khẩu và nhập khẩu văn bản thuần phiên phím bằng cách sử dụng CryptoAPI

QUAN TRỌNG: Bài viết này được dịch bằng phần mềm dịch máy của Microsoft chứ không phải do con người dịch. Microsoft cung cấp các bài viết do con người dịch và cả các bài viết do máy dịch để bạn có thể truy cập vào tất cả các bài viết trong Cơ sở Kiến thức của chúng tôi bằng ngôn ngữ của bạn. Tuy nhiên, bài viết do máy dịch không phải lúc nào cũng hoàn hảo. Loại bài viết này có thể chứa các sai sót về từ vựng, cú pháp hoặc ngữ pháp, giống như một người nước ngoài có thể mắc sai sót khi nói ngôn ngữ của bạn. Microsoft không chịu trách nhiệm về bất kỳ sự thiếu chính xác, sai sót hoặc thiệt hại nào do việc dịch sai nội dung hoặc do hoạt động sử dụng của khách hàng gây ra. Microsoft cũng thường xuyên cập nhật phần mềm dịch máy này.

Nhấp chuột vào đây để xem bản tiếng Anh của bài viết này:228786
TÓM TẮT
Đôi khi nó được thuận tiện để xuất khẩu và nhập khẩu văn bản thuần phiên phím. Tuy nhiên, các Microsoft mật mã cấp (cơ sở và Enhanced) không hỗ trợ tính năng này. Cả hai CryptExportKey() và CryptImportKey() yêu cầu một xử lý chủ chốt hợp lệ để mật mã hóa và giải mã khóa phiên giao dịch, tương ứng. Nhưng bằng cách sử dụng một khóa riêng "số mũ của một" tác dụng tương tự có thể đạt được mật mã hóa và giải mã khóa phiên.
THÔNG TIN THÊM
Bởi vì số mũ quan trọng một, mã hóa và giải mã không phải làm gì để văn bản đơn giản, và như vậy về cơ bản để lại chìa khóa phiên trong văn bản thuần.

Mẫu mã sau đây minh hoạ làm thế nào để thực hiện các tính năng này:
#include <windows.h>#include <wincrypt.h>#include <stdio.h>BOOL CreatePrivateExponentOneKey(LPTSTR szProvider,                                  DWORD dwProvType,                                  LPTSTR szContainer,                                 DWORD dwKeySpec,                                 HCRYPTPROV *hProv,                                  HCRYPTKEY *hPrivateKey);BOOL GenerateSessionKeyWithAlgorithm(HCRYPTPROV hProv,                                      ALG_ID Alg,                                     HCRYPTKEY *hSessionKey);BOOL DeriveSessionKeyWithAlgorithm(HCRYPTPROV hProv,                                    ALG_ID Alg,                                   LPBYTE lpHashingData,                                   DWORD dwHashingData,                                   HCRYPTKEY *hSessionKey);BOOL ExportPlainSessionBlob(HCRYPTKEY hPublicKey,                            HCRYPTKEY hSessionKey,                            LPBYTE *pbKeyMaterial,                            DWORD *dwKeyMaterial);BOOL ImportPlainSessionBlob(HCRYPTPROV hProv,                            HCRYPTKEY hPrivateKey,                            ALG_ID dwAlgId,                            LPBYTE pbKeyMaterial,                            DWORD dwKeyMaterial,                            HCRYPTKEY *hSessionKey);void main(){   HCRYPTPROV hProv = 0;   HCRYPTKEY hPubPrivKey = 0;   HCRYPTKEY hSessionKey = 0;   BOOL fResult;   LPBYTE pbKeyMaterial  = NULL;   DWORD dwKeyMaterial ;      int n;   __try   {      printf("Creating Exponent of One Private Key.\n\n");      // Create Exponent of One private key      fResult = CreatePrivateExponentOneKey(MS_ENHANCED_PROV, PROV_RSA_FULL,                                            "TestContainer", AT_KEYEXCHANGE,                                             &hProv, &hPubPrivKey);      if (!fResult)      {         printf("CreatePrivateExponentOneKey failed with %x\n", GetLastError());         __leave;      }      // Allocate memory for 3DES key and       // Fill key with data 1,2,3,... in this case      pbKeyMaterial = (LPBYTE)LocalAlloc(LPTR, 192/8);      for (n = 0; n < 192/8; n++) pbKeyMaterial[n] = n+1;      dwKeyMaterial = 192/8;      printf("\nImporting 3DES key with key material 1,2,3,...\n");      // Import this key and get an HCRYPTKEY handle      if (!ImportPlainSessionBlob(hProv, hPubPrivKey, CALG_3DES, pbKeyMaterial, dwKeyMaterial, &hSessionKey))      {         printf("ImportPlainSessionBlob failed with %x\n", GetLastError());         __leave;      }      LocalFree(pbKeyMaterial);      pbKeyMaterial = NULL;      printf("Exporting 3DES key.  We should get back 1,2,3,...\n");      // Export it and get the key material back      // It should be 1,2,3, ...      fResult = ExportPlainSessionBlob(hPubPrivKey, hSessionKey,                                        &pbKeyMaterial , &dwKeyMaterial );      if (!fResult)      {         printf("ExportPlainSessionBlob failed with %x\n", GetLastError());         __leave;      }           // Print Key material      printf("3DES session key:\n");      for (n = 0; n < dwKeyMaterial; n++)            {         if (n%8 == 0) printf(" ");         printf("%02x", pbKeyMaterial[n]);      }      printf("\n");   }   __finally   {      if (pbKeyMaterial ) LocalFree(pbKeyMaterial );      if (hSessionKey) CryptDestroyKey(hSessionKey);      if (hPubPrivKey) CryptDestroyKey(hPubPrivKey);      if (hProv)       {           CryptReleaseContext(hProv, 0);         CryptAcquireContext(&hProv, "TestContainer", MS_ENHANCED_PROV,                                     PROV_RSA_FULL, CRYPT_DELETEKEYSET);      }   }}BOOL CreatePrivateExponentOneKey(LPTSTR szProvider,                                  DWORD dwProvType,                                 LPTSTR szContainer,                                 DWORD dwKeySpec,                                 HCRYPTPROV *hProv,                                  HCRYPTKEY *hPrivateKey){   BOOL fReturn = FALSE;   BOOL fResult;   int n;   LPBYTE keyblob = NULL;   DWORD dwkeyblob;   DWORD dwBitLen;   BYTE *ptr;   __try   {      *hProv = 0;      *hPrivateKey = 0;      if ((dwKeySpec != AT_KEYEXCHANGE) && (dwKeySpec != AT_SIGNATURE))  __leave;      // Try to create new container      fResult = CryptAcquireContext(hProv, szContainer, szProvider,                                     dwProvType, CRYPT_NEWKEYSET);      if (!fResult)      {         // If the container exists, open it         if (GetLastError() == NTE_EXISTS)         {            fResult = CryptAcquireContext(hProv, szContainer, szProvider, dwProvType, 0);            if (!fResult)            {               // No good, leave               __leave;            }         }         else         {            // No good, leave            __leave;         }      }      // Generate the private key      fResult = CryptGenKey(*hProv, dwKeySpec, CRYPT_EXPORTABLE, hPrivateKey);      if (!fResult) __leave;      // Export the private key, we'll convert it to a private      // exponent of one key      fResult = CryptExportKey(*hPrivateKey, 0, PRIVATEKEYBLOB, 0, NULL, &dwkeyblob);      if (!fResult) __leave;            keyblob = (LPBYTE)LocalAlloc(LPTR, dwkeyblob);      if (!keyblob) __leave;      fResult = CryptExportKey(*hPrivateKey, 0, PRIVATEKEYBLOB, 0, keyblob, &dwkeyblob);      if (!fResult) __leave;      CryptDestroyKey(*hPrivateKey);      *hPrivateKey = 0;      // Get the bit length of the key      memcpy(&dwBitLen, &keyblob[12], 4);            // Modify the Exponent in Key BLOB format      // Key BLOB format is documented in SDK      // Convert pubexp in rsapubkey to 1      ptr = &keyblob[16];      for (n = 0; n < 4; n++)      {         if (n == 0) ptr[n] = 1;         else ptr[n] = 0;      }      // Skip pubexp      ptr += 4;      // Skip modulus, prime1, prime2      ptr += (dwBitLen/8);      ptr += (dwBitLen/16);      ptr += (dwBitLen/16);      // Convert exponent1 to 1      for (n = 0; n < (dwBitLen/16); n++)      {         if (n == 0) ptr[n] = 1;         else ptr[n] = 0;      }      // Skip exponent1      ptr += (dwBitLen/16);      // Convert exponent2 to 1      for (n = 0; n < (dwBitLen/16); n++)      {         if (n == 0) ptr[n] = 1;         else ptr[n] = 0;      }      // Skip exponent2, coefficient      ptr += (dwBitLen/16);      ptr += (dwBitLen/16);      // Convert privateExponent to 1      for (n = 0; n < (dwBitLen/8); n++)      {         if (n == 0) ptr[n] = 1;         else ptr[n] = 0;      }            // Import the exponent-of-one private key.            if (!CryptImportKey(*hProv, keyblob, dwkeyblob, 0, 0, hPrivateKey))      {                          __leave;      }      fReturn = TRUE;   }   __finally   {      if (keyblob) LocalFree(keyblob);      if (!fReturn)      {         if (*hPrivateKey) CryptDestroyKey(*hPrivateKey);         if (*hProv) CryptReleaseContext(*hProv, 0);      }   }   return fReturn;}BOOL GenerateSessionKeyWithAlgorithm(HCRYPTPROV hProv,                                      ALG_ID Alg,                                     HCRYPTKEY *hSessionKey){      BOOL fResult;   *hSessionKey = 0;   fResult = CryptGenKey(hProv, Alg, CRYPT_EXPORTABLE, hSessionKey);   if (!fResult)   {      return FALSE;   }      return TRUE;   }BOOL DeriveSessionKeyWithAlgorithm(HCRYPTPROV hProv,                                    ALG_ID Alg,                                   LPBYTE lpHashingData,                                   DWORD dwHashingData,                                   HCRYPTKEY *hSessionKey){   BOOL fResult;   BOOL fReturn = FALSE;   HCRYPTHASH hHash = 0;   __try   {      *hSessionKey = 0;      fResult = CryptCreateHash(hProv, CALG_SHA1, 0, 0, &hHash);      if (!fResult) __leave;      fResult = CryptHashData(hHash, lpHashingData, dwHashingData, 0);      if (!fResult) __leave;      fResult = CryptDeriveKey(hProv, Alg, hHash, CRYPT_EXPORTABLE, hSessionKey);      if (!fResult) __leave;      fReturn = TRUE;   }   __finally   {            if (hHash) CryptDestroyHash(hHash);   }   return fReturn;}BOOL ExportPlainSessionBlob(HCRYPTKEY hPublicKey,                            HCRYPTKEY hSessionKey,                            LPBYTE *pbKeyMaterial ,                            DWORD *dwKeyMaterial ){   BOOL fReturn = FALSE;   BOOL fResult;   DWORD dwSize, n;   LPBYTE pbSessionBlob = NULL;   DWORD dwSessionBlob;   LPBYTE pbPtr;   __try   {      *pbKeyMaterial  = NULL;      *dwKeyMaterial  = 0;      fResult = CryptExportKey(hSessionKey, hPublicKey, SIMPLEBLOB,                               0, NULL, &dwSessionBlob );      if (!fResult) __leave;      pbSessionBlob  = (LPBYTE)LocalAlloc(LPTR, dwSessionBlob );      if (!pbSessionBlob) __leave;      fResult = CryptExportKey(hSessionKey, hPublicKey, SIMPLEBLOB,                               0, pbSessionBlob , &dwSessionBlob );      if (!fResult) __leave;      // Get session key size in bits      dwSize = sizeof(DWORD);      fResult = CryptGetKeyParam(hSessionKey, KP_KEYLEN, (LPBYTE)dwKeyMaterial, &dwSize, 0);      if (!fResult) __leave;      // Get the number of bytes and allocate buffer      *dwKeyMaterial /= 8;      *pbKeyMaterial = (LPBYTE)LocalAlloc(LPTR, *dwKeyMaterial);      if (!*pbKeyMaterial) __leave;      // Skip the header      pbPtr = pbSessionBlob;      pbPtr += sizeof(BLOBHEADER);      pbPtr += sizeof(ALG_ID);      // We are at the beginning of the key      // but we need to start at the end since       // it's reversed      pbPtr += (*dwKeyMaterial - 1);            // Copy the raw key into our return buffer            for (n = 0; n < *dwKeyMaterial; n++)      {         (*pbKeyMaterial)[n] = *pbPtr;         pbPtr--;      }                  fReturn = TRUE;   }   __finally   {      if (pbSessionBlob) LocalFree(pbSessionBlob);      if ((!fReturn) && (*pbKeyMaterial ))      {         LocalFree(*pbKeyMaterial );         *pbKeyMaterial  = NULL;         *dwKeyMaterial  = 0;      }   }   return fReturn;}BOOL ImportPlainSessionBlob(HCRYPTPROV hProv,                            HCRYPTKEY hPrivateKey,                            ALG_ID dwAlgId,                            LPBYTE pbKeyMaterial ,                            DWORD dwKeyMaterial ,                            HCRYPTKEY *hSessionKey){   BOOL fResult;      BOOL fReturn = FALSE;   BOOL fFound = FALSE;   LPBYTE pbSessionBlob = NULL;   DWORD dwSessionBlob, dwSize, n;   DWORD dwPublicKeySize;   DWORD dwProvSessionKeySize;   ALG_ID dwPrivKeyAlg;   LPBYTE pbPtr;    DWORD dwFlags = CRYPT_FIRST;   PROV_ENUMALGS_EX ProvEnum;   HCRYPTKEY hTempKey = 0;   __try   {      // Double check to see if this provider supports this algorithm      // and key size      do      {                 dwSize = sizeof(ProvEnum);         fResult = CryptGetProvParam(hProv, PP_ENUMALGS_EX, (LPBYTE)&ProvEnum,                                     &dwSize, dwFlags);         if (!fResult) break;         dwFlags = 0;         if (ProvEnum.aiAlgid == dwAlgId) fFound = TRUE;                                           } while (!fFound);      if (!fFound) __leave;      // We have to get the key size(including padding)      // from an HCRYPTKEY handle.  PP_ENUMALGS_EX contains      // the key size without the padding so we can't use it.      fResult = CryptGenKey(hProv, dwAlgId, 0, &hTempKey);      if (!fResult) __leave;            dwSize = sizeof(DWORD);      fResult = CryptGetKeyParam(hTempKey, KP_KEYLEN, (LPBYTE)&dwProvSessionKeySize,                                 &dwSize, 0);      if (!fResult) __leave;            CryptDestroyKey(hTempKey);      hTempKey = 0;      // Our key is too big, leave      if ((dwKeyMaterial * 8) > dwProvSessionKeySize) __leave;      // Get private key's algorithm      dwSize = sizeof(ALG_ID);      fResult = CryptGetKeyParam(hPrivateKey, KP_ALGID, (LPBYTE)&dwPrivKeyAlg, &dwSize, 0);      if (!fResult) __leave;      // Get private key's length in bits      dwSize = sizeof(DWORD);      fResult = CryptGetKeyParam(hPrivateKey, KP_KEYLEN, (LPBYTE)&dwPublicKeySize, &dwSize, 0);      if (!fResult) __leave;      // calculate Simple blob's length      dwSessionBlob = (dwPublicKeySize/8) + sizeof(ALG_ID) + sizeof(BLOBHEADER);      // allocate simple blob buffer      pbSessionBlob = (LPBYTE)LocalAlloc(LPTR, dwSessionBlob);      if (!pbSessionBlob) __leave;      pbPtr = pbSessionBlob;      // SIMPLEBLOB Format is documented in SDK      // Copy header to buffer      ((BLOBHEADER *)pbPtr)->bType = SIMPLEBLOB;      ((BLOBHEADER *)pbPtr)->bVersion = 2;      ((BLOBHEADER *)pbPtr)->reserved = 0;      ((BLOBHEADER *)pbPtr)->aiKeyAlg = dwAlgId;      pbPtr += sizeof(BLOBHEADER);      // Copy private key algorithm to buffer      *((DWORD *)pbPtr) = dwPrivKeyAlg;      pbPtr += sizeof(ALG_ID);      // Place the key material in reverse order      for (n = 0; n < dwKeyMaterial; n++)      {         pbPtr[n] = pbKeyMaterial[dwKeyMaterial-n-1];      }           // 3 is for the first reserved byte after the key material + the 2 reserved bytes at the end.      dwSize = dwSessionBlob - (sizeof(ALG_ID) + sizeof(BLOBHEADER) + dwKeyMaterial + 3);      pbPtr += (dwKeyMaterial+1);      // Generate random data for the rest of the buffer      // (except that last two bytes)      fResult = CryptGenRandom(hProv, dwSize, pbPtr);      if (!fResult) __leave;      for (n = 0; n < dwSize; n++)      {         if (pbPtr[n] == 0) pbPtr[n] = 1;      }      pbSessionBlob[dwSessionBlob - 2] = 2;      fResult = CryptImportKey(hProv, pbSessionBlob , dwSessionBlob,                                hPrivateKey, CRYPT_EXPORTABLE, hSessionKey);      if (!fResult) __leave;      fReturn = TRUE;              }   __finally   {      if (hTempKey) CryptDestroyKey(hTempKey);      if (pbSessionBlob) LocalFree(pbSessionBlob);   }      return fReturn;}				
THAM KHẢO
Xem MSDN trực tuyến cho thêm thông tin về các API được sử dụng trong mẫu.

Định dạng khoá BLOB được diễn tả tại trang MSDN Web sau đây:
CryptExportKey, CryptImportKey, đồng bằng văn bản phiên phím, Private key với số mũ của một, SIMPLEBLOB.

Cảnh báo: Bài viết này được dịch tự động

Thuộc tính

ID Bài viết: 228786 - Xem lại Lần cuối: 08/21/2011 11:31:00 - Bản sửa đổi: 2.0

Microsoft Win32 Application Programming Interface

  • kbapi kbcrypt kbFAQ kbhowto kbkernbase kbsecurity kbmt KB228786 KbMtvi
Phản hồi