I've updated this to more thoroughly describe what's going on. Hope I haven't broken any rules in doing so.
Second update: changed decryption on the application side (After "The following adapted from...").
I have a text file which I encrypt on a source machine. The resulting file needs to be distributed to a number of destination machines and decrypted on the fly for presentation there. Transmission security is not an issue; our primary concern is with data integrity for reporting purposes; the end user should not be able to edit a free text file - hence, the encryption. On the source machine, my encryption and decryption work fine. This is the source encryption:
HCRYPTPROV m_hCryptProv;
HCRYPTKEY m_hSigKey;
HCRYPTKEY m_hExchKey;
HCRYPTHASH m_hHash;
CMemFile m_file;
CString m_strPassword;
CString m_strData;
CByteArray arData;
CFile file;
DWORD dwBlobLen = 0;
BYTE* pbKeyBlob;
CryptAcquireContext(&m_hCryptProv, NULL, NULL, PROV_RSA_FULL, 0);
CryptCreateHash(m_hCryptProv, CALG_MD5, 0, 0, &m_hHash);
CryptHashData(m_hHash, (const BYTE*)strPassword.GetString(), strPassword.GetLength() * sizeof(TCHAR), 0);
CryptDeriveKey(m_hCryptProv, CALG_RC2, m_hHash, CRYPT_EXPORTABLE, &m_hSigKey);
// m_strData is input to be encrypted
m_crypto.Encrypt(m_strData, arData);
file.Write(arData.GetData(), static_cast<UINT>(arData.GetCount()));
file.Flush();
file.Close();
// encrypted file "file" copied to target machine as "GlobalOperator.dat".
// Generate exchange key and write to file.
CryptGetUserKey(m_hCryptProv, AT_KEYEXCHANGE, &m_hExchKey);
CryptExportKey(m_hExchKey, 0, PUBLICKEYBLOB, 0, NULL, &dwBlobLen);
pbKeyBlob = (BYTE*)malloc(dwBlobLen);
//CryptExportKey(m_hExchKey, 0, PUBLICKEYBLOB, 0, NULL, &dwBlobLen);
CryptExportKey(m_hExchKey, 0, PUBLICKEYBLOB, 0, pbKeyBlob, &dwBlobLen);
file.Write(pbKeyBlob, dwBlobLen);
file.Flush();
file.Close();
// key file "file" copied to target machine as "key.dat".
The target machine(s) run an application an attempts to read the encrypted file:
CString m_strData;
CByteArray arData;
CFile GlobalOperatorFile;
GlobalOperatorFile.Open("GlobalOperator.dat")
arData.SetSize(static_cast<INT_PTR>(GlobalOperatorFile.GetLength()));
GlobalOperatorFile.Read(arData.GetData(), static_cast<UINT>(GlobalOperatorFile.GetLength()));
GlobalOperatorFile.Close();
// Try to deserialize the data.
DWORD dwBlobLen = 0;
CMemFile m_file;
m_file.SetLength(0);
// Write the contents of the byte array to the memory file.
m_file.Write(arData.GetData(), static_cast<UINT>(arData.GetCount()));
m_file.Flush();
// Acquire direct access to the memory file buffer.
BYTE* pData = m_file.Detach();
DWORD dwDataLength = static_cast<DWORD>(arData.GetCount());
// The following adapted from https://docs.microsoft.com/en-us/windows/win32/seccrypto/example-c-program-decrypting-a-file
CryptCreateHash(m_hCryptProv, CALG_MD5, 0, 0, &m_hHash);
CString pwd = "EncryptionKey";
CryptHashData(m_hHash, (const BYTE*)pwd.GetString(), pwd.GetLength() * sizeof(TCHAR), 0);
CryptDeriveKey(m_hCryptProv, CALG_RC2, m_hHash, CRYPT_EXPORTABLE, &m_hKey);
CryptDecrypt(m_hKey, NULL, TRUE, 0, pData, &dwDataLength);
// The above call to CryptDecrypt fails with error code 0x80090005: NTE_BAD_DATA
So I clearly have no idea what I'm doing with encryption/decryption.
Can anyone help?
User contributions licensed under CC BY-SA 3.0