使用<wincrypt.h> </wincrypt.h>在加密 - 解密期间丢失字符

时间:2012-12-11 15:06:40

标签: c++ encryption

我使用“wincrypt.h”基于算法来加密字符串,然后将加密的字符串解密为原始字符串。

类似的东西:

Original -> Encrypt -> Decrypt -> Original

问题是Decrypted 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变为Kolari

1 个答案:

答案 0 :(得分:1)

加密字符串可以包含零字节,实际上任何单个字节为零的可能性为1/256。您假设加密结果是一个以零字节结束的字符串。即使TCHAR是16位而不是8位,你的机会仍然是1/65536。

您需要传递加密结果的长度。