Unable to store value of hex encryption output

May 29, 2010 at 5:56pm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
 unsigned char S[256];
unsigned int i, j;
 
void swap(unsigned char *s, unsigned int i, unsigned int j) {
    unsigned char temp = s[i];
    s[i] = s[j];
    s[j] = temp;
}
 
/* KSA */
void rc4_init(unsigned char *key, unsigned int key_length) {
    for (i = 0; i < 256; i++)
        S[i] = i;
 
    for (i = j = 0; i < 256; i++) {
        j = (j + key[i % key_length] + S[i]) & 255;
        swap(S, i, j);
    }
 
    i = j = 0;
}
 
/* PRGA */
unsigned char rc4_output() {
    i = (i + 1) & 255;
    j = (j + S[i]) & 255;
 
    swap(S, i, j);
 
    return S[(S[i] + S[j]) & 255];
}

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <iostream>
 #include <sstream>
#define ARRAY_SIZE(a) (sizeof(a)/sizeof(a[0]))
 
int main() {

    int y;
    std::string strKey;
    std::string plaintextStr;
    std::cout << "ENTER KEY";
    std::cin >> strKey;
    std::cout << std::endl << "ENTER PLAINTEXT";
    std::cin >> plaintextStr;
    rc4_init(reinterpret_cast<unsigned char*>(const_cast<char *>(strKey.c_str())), strKey.size());
    unsigned char* output = reinterpret_cast<unsigned char*>(const_cast<char *>("")); 
    std::ostringstream tempss;
        std::cout.flags(std::ios::hex);
    for (y = 0; y < plaintextStr.size(); y++)
    {
        printf("%02X", plaintextStr[y] ^ rc4_output()); //this should be the correct output

        unsigned int temp = plaintextStr[y] ^ rc4_output();

        output = output + temp;
    }
    printf("\n");    
    for (y = 0; y < plaintextStr.size(); y++)
    {
        unsigned char temp = plaintextStr[y] ^ rc4_output(); //this seems wrong and corrupted
        printf("%02X", temp);

    }
    printf("\n");
    printf("%p", output);

    system("pause");
    return 0;
}


Hi,

As seen from the above, the C codes involve some form of encryption.

You can see 2 For loops at the above. The first one, which pretty much printf the encrypted text char by char after the XOR and encryption.

However, I need to store this encrypted text into a variable (string/char*). I can't seem to properly store it. The second for loop pretty much store it char by char, and then printf that char out. What I wanted was to store it char by char, and then append it into a string or c-string. However, I realised the storing corrupted the encrypted text, hence I tried to just store it into a char and then printf that char out.

The 2 outputs are totally different. I have already tried signed char, signed int, unsigned int, etc. but none seem to work. The encryption function returns a signed char so I have no idea why it does not work.

TIA.
Last edited on May 29, 2010 at 5:59pm
May 29, 2010 at 11:54pm
output = output + temp;
Pointers don't work that way. They're just integers. If you changed the type of 'output' to unsigned int, the semantics of this line would not change.
If you want string concatenation either use std::string or char arrays and strcat().

unsigned char* output = reinterpret_cast<unsigned char*>(const_cast<char *>(""));
What in god's name are you doing?
Last edited on May 29, 2010 at 11:55pm
May 30, 2010 at 4:27am
Hi, thanks for your reply.

<code>unsigned char* output = reinterpret_cast<unsigned char*>(const_cast<char *>("")); </code>

What I wanted to do was simply initialize the unsigned char* output, same way as

<code>std::string temp = "";
std::string a = "A";
temp = temp + A;
</code>

Sorry I am primary C++ trained and only really used strings. Never really used c-strings before and hence I used this stupid way to initialize it. However, initializing it to an empty string will cause loads of compilation error due to a "" being treated as a const char *, and hence I converted using reinterprete_cast to unsigned char* and a const_cast to remove the const-ness.

Not exactly the best solution, but thats the only way I think of.

As to using string and char[], I already tried but it didn't work. Right now, even line 64 did not work. Comparing line 64 to 55, both output are different, when actually both should give me the same answer since I am using the exact same plaintext and key to create some encrypted text out. The only difference between both lines is, line 55 printf the result straight away without storing into a variable, but line 64 stores it into a char and then printf.

Line 64 store it into a char first because what I wanted was to concatenate the whole thing into 1 single string/char[]. However, when even the individual char is wrong, there is no point concatenating now since that would still give me a wrong result.



Thank you.
Last edited on May 30, 2010 at 4:36am
May 30, 2010 at 8:18am
Oh my goodness ;o)
 
unsigned char* output = reinterpret_cast<unsigned char*>(const_cast<char *>(""));


When this is compiled the location of your "" is quite possible somewhere close to your program code. Writing anything to that address is going to overwrite other static variables at best. Most likely writing to that location will cause a SEGFAULT.

If you want to reserve memory for a char* you need to do it like this:

 
unsigned char output[HOW_BIG_DO_YOU_NEED];


May 30, 2010 at 10:26am
unsigned char* output = reinterpret_cast<unsigned char*>(const_cast<char *>(""));

Why doesn't it serve you if you do it like string output=""; ?

Also, this one: unsigned int temp = plaintextStr[y] ^ rc4_output();

Should be like this: unsigned char temp = plaintextStr[y] ^ rc4_output();
May 30, 2010 at 6:43pm
Hi,
Thanks for all the replies.

1
2
3
unsigned char output[HOW_BIG_DO_YOU_NEED];
output = output + "A"; //will output go crazy? Since it is uninitialized and for Strings, you will have
//random values. 


So if I need to initialize this char array to an initial value, I should use strcat or something so I can set it to ""?

m4ster r0shi, I already tried both unsigned int and unsigned char to hold

1
2
3
4
5
unsigned  char temp = plaintextStr[y] ^ rc4_output();
unsigned  int temp2 = plaintextStr[y] ^ rc4_output();
printf("%02X", plaintextStr[y] ^ rc4_output()); //this should be the correct output
printf("%02X", temp);  //wrong output
printf("%02X", temp2); //wrong output 


Unfortunately, when I printf either the unsigned char and the unsigned int, both gave me wrong values as compared to line 55.

I could have modified the codes to replace them with string and everything, but I wanted to learn from all the experts here the reason behind why my unsigned char and char conversions and printf goes crazy.

Thanks in advance.
May 30, 2010 at 7:14pm
Regarding this:

1
2
unsigned char output[HOW_BIG_DO_YOU_NEED];
output = output + "A";


I don't really know what you are trying to achieve with it.

I suspect your temp should be an unsigned char (rather than an unsigned int);

Do you want to progressively fill your buffer output with the unsigned char value of temp?


1
2
3
4
5
6
7
8
9
10
11

unsigned char output[HOW_BIG_DO_YOU_NEED];
unsigned char* optr = output;

// ...

unsigned char temp = plaintextStr[y] ^ rc4_output();

*optr = temp;
optr++;

Last edited on May 30, 2010 at 7:17pm
May 31, 2010 at 5:52am
Hi Galik,

Yes you are right. Sorry that I am not very clear.

The encryption algorithm works progressively, character by character.

So I will enter a whole string of text to encrypt, and a whole string of text as an encryption key.

However, the original encryption algorithm works progressively, char by char of the original string, and printf out the new encrypted output char by char.

I would like to just store the encrypted output somehow, be it string, c-string, ostringstream, etc.

As long as I can store it into something I can carry on with what I wish to do with the variable. Just printing it out char by char onto screen means I cannot carry on doing stuff with the encrypted text.

Hence, I tried to append it into a string, c-string and ostringstream. However, all 3 approaches gave me different values to the original algorithm.

1
2
3
4
5
6
  
unsigned  char temp = plaintextStr[y] ^ rc4_output(); //1 failed attempt
unsigned  int temp2 = plaintextStr[y] ^ rc4_output(); //also a failed attempt
printf("%02X", plaintextStr[y] ^ rc4_output()); //this should be the correct output
printf("%02X", temp);  //wrong output 
printf("%02X", temp2); //wrong output  


As you can see, the original attempt simply printf it directly out to screen.

The other 2 failed attempts which I tried, either an unsigned char or an unsigned int, both gave me wrong output. I have also tried various int, signed int, char, char*, ostringstream, string, all are wrong.

I guess it has something to do with conversion of unsigned char or the displaying of hex characters.

Thanks in advance.
May 31, 2010 at 8:19am
If you want to mess with the original code as little as possible then you might consider just substituting sprintf() for printf().

That way it will simply fill up a cstring rather than go to the console.
May 31, 2010 at 8:21am
sprintf();
http://www.cplusplus.com/reference/clibrary/cstdio/sprintf/

So instead of this:
 
printf("%02X", plaintextStr[y] ^ rc4_output()); //this should be the correct output 


You could have this:

1
2
3
4
5
char output[BIG_ENOUGH_TO_STORE_YOUR_ENCRYPTED_DATA];

// ...

sprintf(output, "%02X", plaintextStr[y] ^ rc4_output()); //this should be the correct output 
Topic archived. No new replies allowed.