2012-12-11 19 views
1

我使用「wincrypt.h」來基於算法來加密字符串,然後將加密的字符串解密爲原始字符。使用加密解密時丟失的字符<wincrypt.h>

喜歡的東西:

Original -> Encrypt -> Decrypt -> Original 

的問題是解密的原文出來長度短一些情況下(有的話),這個問題是不是字符串或一個或多個字符有關,我的長度已經檢查過。我認爲的問題是使用密鑰(它只是一個隨機字符串),如果我使用不同的密鑰,它會影響完全不同的字/字符串。

下面是代碼:

BOOL SetupCryptoClient() 
    { 
     // Ensure that the default cryptographic client is set up. 
     HCRYPTPROV hProv; 
     HCRYPTKEY hKey;  
     // Attempt to acquire a handle to the default key container. 
     if (!CryptAcquireContext(&hProv, NULL, MS_DEF_PROV, PROV_RSA_FULL, 0)) 
     { 
      // Some sort of error occured, create default key container. 
      if (!CryptAcquireContext(&hProv, NULL, MS_DEF_PROV, PROV_RSA_FULL, CRYPT_NEWKEYSET)) 
      { 
       // Error creating key container!    
       return FALSE;  
      } 
     } 
     // Attempt to get handle to signature key. 
     if (!CryptGetUserKey(hProv, AT_SIGNATURE, &hKey)) 
     { 
      if (GetLastError() == NTE_NO_KEY)  
      {   
       // Create signature key pair. 
       if (!CryptGenKey(hProv, AT_SIGNATURE, 0, &hKey))    
       { 
        // Error during CryptGenKey!     
        CryptReleaseContext(hProv, 0); 
        return FALSE;   
       }   
       else    
       {    
        CryptDestroyKey(hKey);   
       }  
      }  
      else   
      { 
       // Error during CryptGetUserKey!    
       CryptReleaseContext(hProv, 0); 
       return FALSE;  
      } 
     } 

     // Attempt to get handle to exchange key. 
     if (!CryptGetUserKey(hProv,AT_KEYEXCHANGE,&hKey)) 
     { 
      if (GetLastError()==NTE_NO_KEY)  
      {   
       // Create key exchange key pair. 
       if (!CryptGenKey(hProv,AT_KEYEXCHANGE,0,&hKey))   
       { 
        // Error during CryptGenKey!     
        CryptReleaseContext(hProv, 0); 
        return FALSE;   
       }   
       else    
       {    
        CryptDestroyKey(hKey);   
       }  
      }  
      else   
      { 
       // Error during CryptGetUserKey!    
       CryptReleaseContext(hProv, 0); 
       return FALSE;  
      } 
     } 

     CryptReleaseContext(hProv, 0); 
     return TRUE; 
    } 



    BOOL EncryptString(TCHAR* szPassword,TCHAR* szEncryptPwd,TCHAR *szKey) 
    { 
     BOOL bResult = TRUE;  
     HKEY hRegKey = NULL;  
     HCRYPTPROV hProv; 
     HCRYPTKEY hKey; 
     HCRYPTKEY hXchgKey; 
     HCRYPTHASH hHash; 
     DWORD dwLength; 
     // Get handle to user default provider. 
     if (CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_FULL, 0)) 
     { 
      // Create hash object.  
      if (CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash))  
      { 
       // Hash password string.    
       dwLength = sizeof(TCHAR)*_tcslen(szKey); 
       if (CryptHashData(hHash, (BYTE *)szKey, dwLength, 0))   
       { 
        // Create block cipher session key based on hash of the password. 
        if (CryptDeriveKey(hProv, MY_ENCRYPT, hHash, CRYPT_EXPORTABLE, &hKey))    
        { 
         // Determine number of bytes to encrypt at a time. 
         dwLength = sizeof(TCHAR)*_tcslen(szPassword);     
         // Allocate memory. 
         BYTE *pbBuffer = (BYTE *)malloc(dwLength);     
         if (pbBuffer != NULL)     
         { 
          memcpy(pbBuffer, szPassword, dwLength);      
          // Encrypt data 
          if (CryptEncrypt(hKey, 0, TRUE, 0, pbBuffer, &dwLength, dwLength))      
          { 
           // return encrypted string 
           memcpy(szEncryptPwd, pbBuffer, dwLength); 

          } 
          else       
          {       
           bResult = FALSE;       
          }      
          // Free memory 
          free(pbBuffer);     
         } 
         else      
         {      
          bResult = FALSE;      
         } 
         CryptDestroyKey(hKey); // Release provider handle.    
        }    
        else     
        { 
         // Error during CryptDeriveKey!     
         bResult = FALSE;     
        }   
       }   
       else    
       { 
        // Error during CryptHashData!    
        bResult = FALSE;    
       } 
       CryptDestroyHash(hHash); 
       // Destroy session key.  
      }  
      else   
      { 
       // Error during CryptCreateHash!    
       bResult = FALSE;   
      } 
      CryptReleaseContext(hProv, 0); 
     } 
     return bResult; 
    } 



    BOOL DecryptString(TCHAR* szEncryptPwd,TCHAR* szPassword,TCHAR *szKey) 
    { 
     BOOL bResult = TRUE;  
     HCRYPTPROV hProv;  
     HCRYPTKEY hKey;  
     HCRYPTKEY hXchgKey; 
     HCRYPTHASH hHash; 
     TCHAR szPasswordTemp[32] = _T(""); 
     DWORD dwLength; 
     // Get handle to user default provider. 
     if (CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_FULL, 0))  
     { 
      // Create hash object.   
      if (CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash)) 
      {    
       // Hash password string. 
       dwLength = sizeof(TCHAR)*_tcslen(szKey); 
       if (CryptHashData(hHash, (BYTE *)szKey, dwLength, 0))    
       { 
        // Create block cipher session key based on hash of the password. 
        if (CryptDeriveKey(
         hProv, MY_ENCRYPT, hHash, CRYPT_EXPORTABLE, &hKey))     
        { 
         // we know the encrypted password and the length 
         dwLength = sizeof(TCHAR)*_tcslen(szEncryptPwd);      
         // copy encrypted password to temporary TCHAR 
         _tcscpy(szPasswordTemp,szEncryptPwd); 
         if (!CryptDecrypt(
           hKey, 0, TRUE, 0, (BYTE *)szPasswordTemp, &dwLength)) 
          bResult = FALSE;       
         CryptDestroyKey(hKey); // Release provider handle.     
         // copy decrypted password to outparameter 
         _tcscpy(szPassword,szPasswordTemp); 
        }     
        else      
        { 
         // Error during CryptDeriveKey!      
         bResult = FALSE;      
        }    
       }    
       else 
       {     
        // Error during CryptHashData!     
        bResult = FALSE;     
       } 
       CryptDestroyHash(hHash); // Destroy session key.    
      }   
      else    
      { 
       // Error during CryptCreateHash!     
       bResult = FALSE;    
      } 
      CryptReleaseContext(hProv, 0);  
     }  
     return bResult; 
    } 

這是我怎麼稱呼它:

TCHAR szEncrypt[32] = _T(""); 
EncryptString(myString, szEncrypt, szKey); 

TCHAR szDecrypt[32] = _T(""); 
DecryptString(szEncrypt, szDecrypt, szKey); 

注:該代碼是不是我的。

編輯:使用鍵「MZ6 @ a0i *」變成Kolaris到科拉里

+0

你可以舉一個輸入和輸出的例子嗎? –

+0

@Duncan Jones我已經更新了上面的帖子以包含一個例子。 – StudentX

回答

1

加密的字符串可以包含一個零字節,其實機會是1/256對任何個人字節爲零。假設加密結果是一個以零字節結尾的字符串。即使TCHAR是16位而不是8位,你的機會仍然是1/65536。

您需要傳遞加密結果的長度。

+0

它的工作原理時,我通過長度+ 1但不是當我只傳遞length.I試圖strlen()與char *和string.lenght()與std :: strings.While傳遞長度+ 1如果原始字符串有一個它裏面的白色空間就像「科拉里斯」一樣,那麼輸出結尾還有一個額外的字符。現在完全混淆了。 – StudentX

+1

@StudentX,如果以任何方式更改輸入*,輸出也會改變,並且可能不會再包含null。 * *結果*的長度需要保持不變,加密函數應該以某種方式返回給您。 –