Click here to Skip to main content
14,698,679 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Hi all,
I have been trying to write encrypt and decrypt functions whose signatures require the input and the output strings to be in 'void*' type only. The code works fine if the inputs can be specified as IBuffer^ but in the other case the source string and the encrypted->decrypted string do not match. I've googled a lot but to no good. Please help...it's urgent.

IBuffer^ byteArrayToIBufferPtr(byte *source, int size)
{
	Platform::ArrayReference<uint8> blobArray(source, size);
	IBuffer ^buffer = CryptographicBuffer::CreateFromByteArray(blobArray);
	return buffer;
}

byte* IBufferPtrToByteArray(IBuffer ^buffer)
{
	Array<unsigned char,1U> ^platArray = ref new Array<unsigned char,1U>(256);
	CryptographicBuffer::CopyToByteArray(buffer,&platArray);

	byte *dest = platArray->Data;
	return dest;
}

int DataEncryption::encryptData(EncryptionAlgorithm algo, int keySize, void* srcData, const unsigned int srcSize,
		void*& encData, unsigned int& encSize)
{

	LOG_D(TAG, "encryptData()");

	if(srcData == nullptr)
	{
		LOG_E(TAG,"");
		return DataEncryption::RESULT_EMPTY_DATA_ERROR;
	}
	if(srcSize == 0)
	{
		LOG_E(TAG,"");
		return DataEncryption::RESULT_SIZE_ZERO_ERROR;
	}

	IBuffer^ encrypted;
    IBuffer^ buffer;
    IBuffer^ iv = nullptr;
	String^ algName;
	bool cbc = false;

	switch (algo)
	{
	case DataEncryption::ENC_DEFAULT:
		algName = "AES_CBC";
		cbc = true;
		break;
	default:
		break;
	}

	// Open the algorithm provider for the algorithm specified on input.
    SymmetricKeyAlgorithmProvider^ Algorithm = SymmetricKeyAlgorithmProvider::OpenAlgorithm(algName);

    // Generate a symmetric key.
    IBuffer^ keymaterial = CryptographicBuffer::GenerateRandom((keySize + 7) / 8);
    CryptographicKey^ key;

    try
    {
        key = Algorithm->CreateSymmetricKey(keymaterial);
    }
    catch(InvalidArgumentException^ e)
    {
		LOG_E(TAG,"encryptData(): Could not create key.");
		return DataEncryption::RESULT_ERROR;
    }

    // CBC mode needs Initialization vector, here just random data.
    // IV property will be set on "Encrypted".
    if (cbc)
        iv = CryptographicBuffer::GenerateRandom(Algorithm->BlockLength);

    // Set the data to encrypt. 
	IBuffer ^srcDataBuffer = byteArrayToIBufferPtr(static_cast<byte*>(srcData),256);

    // Encrypt and create an authenticated tag.
    encrypted = CryptographicEngine::Encrypt(key, srcDataBuffer, iv);

	//encData = encrypted;
	byte *bb = IBufferPtrToByteArray(encrypted);
	encData = IBufferPtrToByteArray(encrypted);
	encSize = encrypted->Length;

	return DataEncryption::RESULT_SUCCESS;
}


int DataEncryption::decryptData(EncryptionAlgorithm algo, int keySize, void* encData, const unsigned int encSize,
		void*& decData, unsigned int& decSize)
{
	LOG_D(TAG, "decryptData()");

	if(encData == nullptr)
	{
		LOG_E(TAG,"");
		return DataEncryption::RESULT_EMPTY_DATA_ERROR;
	}
	if(encSize == 0)
	{
		LOG_E(TAG,"");
		return DataEncryption::RESULT_SIZE_ZERO_ERROR;
	}

	IBuffer^ encrypted;
    IBuffer^ decrypted;
    IBuffer^ iv = nullptr;
	String^ algName;
	bool cbc = false;

	switch (algo)
	{
	case DataEncryption::ENC_DEFAULT:
		algName = "AES_CBC";
		cbc = true;
		break;
	default:
		break;
	}

	// Open the algorithm provider for the algorithm specified on input.
    SymmetricKeyAlgorithmProvider^ Algorithm = SymmetricKeyAlgorithmProvider::OpenAlgorithm(algName);

    // Generate a symmetric key.
    IBuffer^ keymaterial = CryptographicBuffer::GenerateRandom((keySize + 7) / 8);
    CryptographicKey^ key;

    try
    {
        key = Algorithm->CreateSymmetricKey(keymaterial);
    }
    catch(InvalidArgumentException^ e)
    {
		LOG_E(TAG,"encryptData(): Could not create key.");
		return DataEncryption::RESULT_ERROR;
    }

    // CBC mode needs Initialization vector, here just random data.
    // IV property will be set on "Encrypted".
    if (cbc)
        iv = CryptographicBuffer::GenerateRandom(Algorithm->BlockLength);

    // Set the data to decrypt. 
	byte *cc = static_cast<byte*>(encData);
	IBuffer ^encDataBuffer = byteArrayToIBufferPtr(cc,256);
    // Decrypt and verify the authenticated tag.
    decrypted = CryptographicEngine::Decrypt(key, encDataBuffer, iv);

	byte *bb = IBufferPtrToByteArray(decrypted);
	decData = IBufferPtrToByteArray(decrypted);

	decSize = decrypted->Length;

	return DataEncryption::RESULT_SUCCESS;
}
Posted

I am calling the encode and decode functions in my unit test cases. Below is an extract from them.

Here the source data (pData) and the encrypted and then decrypted data (pDecryptedData) should have eventually come to be the same string i.e; "SampleTextSampleSampleTextSampleSampleTextSampleSampleTextSampleSampleTextSampleSampleTextSampleSampleTextSampleSampleTextSample"

but that is not happening. pDecryptedData is something weird.

char pData[] = "SampleTextSampleSampleTextSampleSampleTextSampleSampleTextSampleSampleTextSampleSampleTextSampleSampleTextSampleSampleTextSample";

DataEncryption::encryptData(DataEncryption::ENC_DEFAULT, 256, pData, sizeof(pData), pEncryptedData, encryptedLength)

DataEncryption::decryptData(DataEncryption::ENC_DEFAULT, 256, pEncryptedData, encryptedLength, pDecryptedData, decryptedLength)

if(!strcmp(pData,static_cast<char*>(pDecryptedData)))
{
	cout<<"Same";
}
else
{
	cout<<"Not Same";
}
   
Comments
Jiří Miklík 27-May-13 6:18am
   
What is weird on pDecryptedData ?
Did you write both strings ?
Are same by content and also by lenght ?
Is pDecryptedData zero-terminated ?
   
pDecryptedData is supposed to contain the return value of the decryptData(). Since pData is encrypted to pEncryptedData which in turn is decrypted to pDecryptedData; logically pData and pDecryptedData should be equal in content. Unfortunately this is not happening. once they both become equal in content, my logic should be satisfied.
Jiří Miklík 27-May-13 10:43am
   
strcmp() compares two zero-terminated strings. Your DataEncryption::buffer looks like a common piece of memory limited by length. Propably there are no terminating zero bytes.
Try:
cout<<pData<<endl;
cout<<pEncryptedData<<endl;

I assume that the second command will fail.
Then you have to terminate the buffer like:

pDecryptedData[decryptedLength] = 0;
Not enough information.
Comparison of CONST CHAR* strings may be optimized.
Result of decription can't be logicaly CONST CHAR*.

But mainly I don't know what you mean with...
"if the inputs can be specified as IBuffer^ but in the other case the source string and the encrypted->decrypted string do not match"

What is input, where is used, how is used.... code missing.
   

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)




CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900