user3105142
user3105142

Reputation: 13

C Xor Encryption (beginner)

I found This Code for xor encryption and it works

string encryptDecrypt(string toEncrypt)
{
    char key = 'K'; //Any char will work
    string output = toEncrypt;
    int z = toEncrypt.size();

    for (int i = 0; i < z; i++)
    {
        output[i] = toEncrypt[i] ^ key;
    }
    return output; 
}

int main(int argc, const char * argv[])
{
    string encrypted = encryptDecrypt("kylewbanks.com");

    string decrypted = encryptDecrypt(encrypted);
    return 0;
}

but when I changed it to this form:

CHAR* encryptDecrypt(CHAR* toEncrypt)
{
     char key = 'K'; //Any char will work
     CHAR* output = toEncrypt;

     for (int i = 0; i < strlen(toEncrypt); i++)
     {
        output[i] = toEncrypt[i] ^ key;
     }
     return output;
 }

 int main(int argc, CHAR* argv[])
 {
     CHAR* encrypted = encryptDecrypt("kylewbanks.com");
     CHAR* decrypted = encryptDecrypt(encrypted);
     return 0;
 }

the program break with this message: Access violation writing location 0x001CCC90

I need to use CHAR* or WCHAR* for my variable (I don't have permission to use string)

the questions are:

1- what is the problem in second code?

2- how can I change key to a word not a character?

thanks for help :)

Edit:

the problem is that it breaks immediately after the line 7

it doesn't do this line at all:

output[i] = toEncrypt[i] ^ key;

Upvotes: 0

Views: 4176

Answers (2)

Vinz
Vinz

Reputation: 3198

1- what is the problem in second code?

As far as I understand you, you want to encrypt and decrypt a c-string. Strings in C are usually character arrays and terminated with a 0. Also you use the pointer arithmetics wrong here.

While:

string output = toEncrypt;

does a copy operation of the whole string,

CHAR* output = toEncrypt;

will just create a new pointer and let it point to the same point where the pointer toEncrypt points at atm. So at the end you just have 2 pointers pointing to the same position which is as good as using 1 pointer at all.

I would suggest that you make a new buffer in that method to store the encrypted data:

CHAR* output = new CHAR[strlen(toEncrypt)];

Though this could lead to undefined behavior if you don't encrypt zero terminated strings. As strlen would continue counting characters until it finds a 0. So I also suggest you to send the lenght of the data to encrypt to your function:

CHAR* encryptDecrypt(CHAR* toEncrypt, int length)

Also readonly character initializations are always constant in C.

So a possible solution would be:

wchar_t* encryptDecrypt(const wchar_t* toEncrypt, int length)
{
    wchar_t key = L'K'; //Any char will work
    wchar_t* output = new wchar_t[length];  // Make a temporary buffer

    for (int i = 0; i < length; i++)
    {
        output[i] = toEncrypt[i] ^ key; // Encrypt every char of the array to encrypt
    }
    return output;
}

int main(int argc, CHAR* argv[])
{
    // Your Data to encrypt / decrypt
    const wchar_t* sourceString = L"kylewbanks.com";
    const int sourceStrLen = wcslen(sourceString); // Get the lenght of your data before you encrypt it and can't use wcslen anymore. Alternatively just enter the amount of characters in your string here.

    // Encrypt / Decrypt your String
    wchar_t* encrypted = encryptDecrypt(sourceString, sourceStrLen);
    wchar_t* decrypted = encryptDecrypt(encrypted, sourceStrLen);

    // Free the allocated buffers
    delete[] encrypted;
    delete[] decrypted;

    return 0;
}

Note that if you want to display this string somewhere using methods like printf(), it will probably display some memory garbage after your string as the encryption returns just the encrypted data which is not zero-terminated.

2- how can I change key to a word not a character?

You could use several methods of XORing with the Key-String but one of the most simple ways would be to XOR the source string with the key-string over and over.

Something like:

    kylewbanks.com
XOR keykeykeykeyke
__________________
    RESULT

if your key-string is "key"

Possible solution:

wchar_t* encryptDecrypt(const wchar_t* toEncrypt, int length)
{
    const wchar_t* key = L"KEY"; // A readonly wide String
    wchar_t* output = new wchar_t[length];  // Make a temporary buffer

    for (int i = 0; i < length; i++)
    {
        output[i] = toEncrypt[i] ^ key[i % wcslen(key)];    // i % 3 wil be ascending between 0,1,2
    }
    return output;
}

Upvotes: 1

Yang Yuan
Yang Yuan

Reputation: 176

1, In encryptDecrypt output is a local variable and link to a static string area, it is readonly. Usually you need to create a buffer space and pass it into encryptDecrypt. malloc inside the function also works but you need to free it manually. BTW, strlen is also dangerous because the encrypted data may not be a valid string.

2, use WCHAR and wcslen instead of CHAR and strlen, key use L'k' should work.

Upvotes: 4

Related Questions