XOR Encrypted Message length is showing wrongly in C [closed] - c

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 5 years ago.
Improve this question
Im Encrypting the Original Messages using XOR algorithm by following code in C program. And Finally it gives another different value that message has encrypted. It should return same length even after the message has encrypted.
But, Using strlen(encrypted) it gives less value than original message length. I couldn't recognize why the length of XOR encrypted message is showing less than the original message length. Please find the following the code to solve my problem.
Thanks in Advance!
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
char* XORCipher(char* data, char* key, int dataLen, int keyLen) {
char* output = (char*)malloc(sizeof(char)*dataLen);
for(int i = 0; i < dataLen; ++i) {
output[i] = data[i] ^ key[i % keyLen];
}
return output;
}
int main(){
char *msg = "This is a Message from Boss";
char *key = "nandha";
int dataLen = strlen(msg);
int keyLen = strlen(key);
char *encrypt = XORCipher(msg,key,dataLen,keyLen);
printf("\nEncrypted msg is :\n %s",(char*)encrypt);
//The Length of encrypted char size is showing wrongly.
printf("size of Encrypted msg is: %d\n",strlen(encrypt));
encrypt = XORCipher(encrypt,key,strlen(encrypt),keyLen);
printf("\nOriginal msg converted is : %s\n",encrypt);
return 0;
}

When you perform these XOR operations on your string, the resulting values could fall outside the range of printable characters. In particular, if a plaintext character happens to match the key character used to encode it the result will be 0.
In C, a string is actually a sequence of characters terminated by a null byte, i.e. a byte with value 0. Any function that operates on strings looks for this byte to denote the end of the string.
Because your encoding can generate null bytes, your encrypted message is not a string but an array of bytes. Attempting to use a string function on the encrypted message can cause it to stop processing in the middle of the message if it contains a null byte. If the message does not contain a null byte, these string functions will continue to read past the end of the character array until it finds one. Reading past the end of an array or dynamically allocated block of memory invoked undefined behavior.
You need some other way to know how long the encrypted message is. In the case of the XOR encoding you're doing this is easy: the length of the ciphertext is the same as the length of the plaintext. So when decoding, pass in dataLen for the ciphertext length. To print the ciphertext, you need to loop through the bytes and print each one individually rather that trying to print it as a string (which it is not).
Also, after you've decoded, you still don't have a string because there was no null terminating byte added to the end of the decrypted message. You can do this manually after calling decrypting:
// pass in plaintext length as ciphertext length since they are the same
encrypt = XORCipher(encrypt,key,dataLen,keyLen);
// null terminate decrypted string
encrypt[dataLen] = '\0';
The buffer allocated inside of XORCipher doesn't currently allocate enough space for the null terminator, so you need to increase this by 1 to allow for this:
// no need to cast the return value of malloc
// sizeof(char) is guaranteed to be 1, so no need to multiply by it
char* output = malloc(dataLen + 1);

C strings are character arrays that are null terminated. When you allocate your encrypted array with the length of the string, you don't leave room for null termination, so strlen is unable to tell when the string ends, thinking the string ends outside of the actual memory that you allocated. This modification to your xor function will make it work.
char* XORCipher(char* data, char* key, int dataLen, int keyLen) {
char* output = (char*)malloc(sizeof(char)*dataLen+1);
output[dateLen] = 0;
for(int i = 0; i < dataLen; ++i) {
output[i] = data[i] ^ key[i % keyLen];
}
return output;
}
Additionally, if you're xor function gives 0 as an output, strlen will see that as the end of the string, which would give you a string length shorter than the expected output.
Update: I have tested the code and it works.
char* XORCipher(char* data, char* key, unsigned long dataLen, unsigned long keyLen) {
char* output = (char*)malloc(sizeof(char)*dataLen+1);
output[dataLen] = 0;
for(int i = 0; i < dataLen; ++i) {
output[i] = data[i] ^ key[i % keyLen];
}
return output;
}
void printLn(char* toPrint, unsigned long len){
for (unsigned long i = 0; i < len; i++) {
printf("%c", toPrint[i]);
}
printf("\n");
}
int main(){
char *msg = "This is a Message from Boss";
char *key = "nandha";
unsigned long dataLen = strlen(msg);
unsigned long keyLen = strlen(key);
printLn(msg, dataLen);
char* xorMessage = XORCipher(msg, key, dataLen, keyLen);
printLn(xorMessage, dataLen);
xorMessage = XORCipher(xorMessage, key, dataLen, keyLen);
printLn(xorMessage, dataLen);
return 0;
}
Be reminded that xoring can result in null characters in the array that you've allocated, resulting in a terminating character which you might have not intended. To compensate for this, I have added a function to print out based on length since you know this information based on your msg. After xoring twice you should have your original string back, which I my code verified.

Related

Converting massive binary input string into character string C

I'm not familiar with C at all so this might be a simple problem to solve. I'm trying to take an input char* array of binary character sequences, ex. "0100100001101001", and output its relative string ("Hi"). The problem I'm having is coming up with a way to split the input into seperate strings of length 8 and then convert them individually to ulimately get the full output string.
char* binaryToString(char* b){
char binary[8];
for(int i=0; i<8; ++i){
binary[i] = b[i];
}
printf("%s", binary);
}
I'm aware of how to convert 8-bit into its character, I just need a way to split the input string in a way that will allow me to convert massive inputs of 8-bit binary characters.
Any help is appreciated... thanks!
From what I can tell, your binaryToString() function does not do what you'd want it to. The print statement just prints the first eight characters from the address pointed to by char* b.
Instead, you can convert the string of 8 bits to an integer, utilizing a standard C function strtol(). There's no need to convert any further, because binary, hex, decimal, etc, are all just representations of the same data! So once the string is converted to a long, you can use that value to represent an ASCII character.
Updating the implementation (as below), you can then leverage it to print a whole sequence.
#include <stdio.h>
#include <string.h>
void binaryToString(char* input, char* output){
char binary[9] = {0}; // initialize string to 0's
// copy 8 bits from input string
for (int i = 0; i < 8; i ++){
binary[i] = input[i];
}
*output = strtol(binary,NULL,2); // convert the byte to a long, using base 2
}
int main()
{
char inputStr[] = "01100001011100110110010001100110"; // "asdf" in ascii
char outputStr[20] = {0}; // initialize string to 0's
size_t iterations = strlen(inputStr) / 8; // get the # of bytes
// convert each byte into an ascii value
for (int i = 0; i < iterations; i++){
binaryToString(&inputStr[i*8], &outputStr[i]);
}
printf("%s", outputStr); // print the resulting string
return 0;
}
I compiled this and it seems to work fine. Of course, this can be done cleaner and safer, but this should help you get started.
I just need a way to split the input string in a way that will allow me to convert massive inputs of 8-bit binary characters.
You can use strncpy() to copy the sequence of '0' and '1' in a chunk of 8 characters at a time from the input string, something like this:
//get the size of input string
size_t len = strlen(b);
//Your input array of '0' and '1' and every sequence of 8 bytes represents a character
unsigned int num_chars = len/8;
//Take a temporary pointer and point it to input string
const char *tmp = b;
//Now copy the 8 chars from input string to buffer "binary"
for(int i=0; i<num_chars; ++i){
strncpy(binary, tmp+(i*8), 8);
//do your stuff with the 8 chars copied from input string to "binary" buffer
}
Maybe this can help. I didnt compile it but there is the idea. You can loop every 8 bit separately with while loop. And assign 8 bit to binary array with for loop. After that send this binary array to convert8BitToChar function to get letter equivalent of 8 bit. Then append the letter to result array. I'm not writing c for 3 year if there is mistakes sorry about that. Here pseudo code.
char* binaryToString(char* b){
char* result = malloc(sizeof(256*char));
char binary[8];
int nextLetter = 0;
while (b[nextLetter*8] != NULL) { // loop every 8 bit
for(int i=0; i<8; ++i){
binary[i] = b[nextLetter*8+i];
}
result[nextLetter] = 8bitToChar(binary));// convert 8bitToChar and append yo result
nextLetter++;
}
result[nextLetter] = '\0';
return result;
}

Assigning part of a string to a char * in C

I want to copy X to Y words of a string to the out char * array.
unsigned char * string = "HELLO WORLD!!!" // length 14
unsigned char out[9];
size_t length = 9;
for(i=0 ;i < length ;++i)
{
out[i] = string[i+3];
}
printf("%s = string\n%s = out\n", string, out);
When looking at the output of out, why is there gibberish after a certain point of my string? I see the string of out as LO WORLD!# . Why are there weird characters appearing after the content I copied, isn't out supposed to be a an array of 9? I expected the output to be
LO WORLD!
In C you need to terminate your string with a 0x00 value so a string of length 9 needs ten bytes to store it with the last set to 0. Otherwise your print statements run off into random data.
unsigned char * string = "HELLO WORLD!!!" // length 14
unsigned char out[10];
size_t length = 9;
for(i=0 ;i < length ;++i)
{
out[i] = string[i+3];
}
out[length] = 0x00;
printf("%s = string\n%s = out\n", string, out);
A minor point, but string literals have type char* (or const char* in C++), not unsigned char* -- these might be the same in your implementation, but they don't need to be.
Furthermore, this is not true:
unsigned char * string = "HELLO WORLD!!!" // length 14
The string actually occupies 15 bytes -- there is an extra, hidden '\0' at the end, called a nul byte, which marks the end of the string. These nul terminators are very important, because if they're not present, then many C library functions which manipulate strings will keep going until they hit a byte with a value equal to '\0' -- and so can end up reading or trampling over bits of memory they shouldn't do. This is called a buffer overrun, and is a classic bug (and exploitable security problem) in C programmes.
In your example, you haven't included this nul terminator in your copied string, so printf() just keeps going until it finds one, hence the gibberish you're seeing. In general, it's a good idea only to use C library functions to manipulate C strings if possible, as these are careful to add the terminator for you. In this case, strncpy from string.h does exactly what you're after.
A 9 character string needs 10 bytes because it must be null ( 0 ) terminated. Try this:
unsigned char out[10]; // make this 10
size_t length = 9;
for(i=0 ;i < length ;++i)
{
out[i] = string[i+3];
}
out[i] = 0; // add this to terminate the string
A better approach would be just the line:
strncpy(out, string+3, 9);
C strings must be null terminated. You only created an array large enough for 8 characters + the null terminator, but you never added the terminator.
So, you need to allocate the length plus 1 and add the terminator.
// initializes all elements to 0
char out[10] = {0};
// alternatively, add it at the end.
out[9] = '\0';
Think of it this way; you're passed a char* which represents a string. How do you know how long it is? How can you read it? Well, in C, a sentinel value is added to the end. This is the null terminator. It is how strings are read in C, and passing around unterminated strings to functions which expect C strings results in undefined behavior.
And then... just use strncpy to copy strings.
If you want to have copy 9 characters from your string, you'll need to have an array of 10 to do that. It is because a C string needs to have '\0' as null terminated character. So your code should be rewritten like this:
unsigned char * string = "HELLO WORLD!!!" // length 14
unsigned char out[10];
size_t length = 9;
for(i=0 ;i < length ;++i)
{
out[i] = string[i+3];
}
out[9] = 0;
printf("%s = string\n%s = out\n", string, out);

Make a long string of encrypted substrings in c

I'm trying to create a long string that is produced out of encrypted substrings. For the encryption I'm using AES128 and libmcrypt. The code is working, but I get a shorter output then I should and a beeping sound. I guess it's because I'm using strlen, but I have no idea, how I can avoid that. I will be very grateful for some suggestions. Here is my code:
char *Encrypt( char *key, char *message){
static char *Res;
MCRYPT mfd;
char *IV;
int i, blocks, key_size = 16, block_size = 16;
blocks = (int) (strlen(message) / block_size) + 1;
Res = calloc(1, (blocks * block_size));
mfd = mcrypt_module_open(MCRYPT_RIJNDAEL_128, NULL, "ecb", NULL);
mcrypt_generic_init(mfd, key, key_size, IV);
strncpy(Res, message, strlen(message));
mcrypt_generic(mfd, Res, block_size);
//printf("the encrypted %s\n", Res);
mcrypt_generic_deinit(mfd);
mcrypt_module_close(mfd);
return (Res);
}
char *mkline ( int cols) {
int j;
char seed[] = "thesecretmessage", key1[]="dontusethisinput", key2[]="abadinputforthis";
char *encrypted, *encrypted2, *in = malloc(cols * 16);
encrypted = Encrypt(key1, seed);
sprintf(in, "%s", encrypted);
encrypted2= Encrypt(key2, encrypted);
printf("encrypted2 before for-loop %s\n", encrypted2);
printf("encrypted2 before for loop len %d\n", strlen(encrypted2));
for (j=1; j<cols; j++) {
strcat(in, encrypted2);
memmove(encrypted2, Encrypt(key2, encrypted2),strlen(seed));
printf("encrypted2 %s on position %d\n" , encrypted2,j);
printf("encrypted2 len %d\n", strlen(encrypted2));
}
free(encrypted);
free(encrypted2);
return in;
}
int main(int argc, char *argv[]) {
char *line = mkline(15);
printf("line %s\n", line);
printf("line lenght %d\n", strlen(line));
return 0;
}
You get the beep sound because you are printing control character.
Also strlen return the size until the first '\0' character (because strings are zero terminated). That's why you get length less than you expect since the encrypted message may contain zeroes.
You can do something like this to return the result length:
char *Encrypt(const char *key, const char *message, int *result_len)
{
*result_len = blocks * block_size;
}
Also
memmove(encrypted2, Encrypt(key2, encrypted2),strlen(seed));
This line should produce a memory leak since every time you call Encrypt you call calloc (allocate new memory) which you need to free after you are done.
You probably should use memcpy, memmove is primarly used if there is a chance destination and source may overlap.
The encrypted string you are trying to print contains a stream of bytes where the value of the individual byte ranges from 0 to 255. Because you are using a cryptographically secure algorithm, the distribution of values is very close to even.
Since you are trying to print the encrypted string through a console, the console interprets some of the bytes as control characters (see Bell character) that are unprintable but have other effects instead, such as playing beeps.
Furthermore, strlen isn't doing what you think it should be doing because the encrypted string is not null-terminated, but instead contains zeroes amongst other bytes and they have no special meaning unlike in NULL terminated strings. You need to store the length of the string elsewhere.
Simple, you are treating binary output (any byte value) directly as printable text. Any character wit a code point below 32 (hex 20) isn't. E.g. the ASCII value for BELL (look it up) could be meaningful to you. Print the resulting bytes in hexadecimals and you should be ok.
I should like to add that in general it is good practice to clear any memory that held the plaintext/unencrypted message after you encrypt it if you can. This is not good coding practice, but good cryptology practice.
This can be done by:
memset(buffer, 0, length_of_buffer);
Don't worry, that won't be optimized out by your compiler. It's actually not smart enough to tell if you'll be using that area again or not.

How to send and receive data socket TCP (C/C++) [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
What is the correct way of reading from a TCP socket in C/C++?
I'm trying to develop a TCP client/server. My problem is, when I try to send the data from cliente I do it in one sent.
But my problem appears when I try to receive the data with a specific structure, I mean, the first 8 bytes set a date, the next 10 a name, and undefined number of bytes set a text (this text ends with /r/n/r/n)
The client sends as follows:
char date[8];
char name[10];
char msg[4096];
strcpy(msg,"12/10/12"); //8 bytes
strcat(msg,"Kevin Fire"); //10 bytes
strcat(msg,"abcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcde\r\n\r\n");
nbytes_sent = send(sock,(char *)msg,sizeof(msg),0);
printf("Bytes_sent: %s -> %i\n",msg,nbytes_sent);
And the server try to parse the data from socket as follows:
char date[8];
char name[10];
char * text;
char buf[1024];
int i=0;
for(i=0; i < 8; i++)
date[i] = '\0';
for(i=0; i < 10; i++)
name[i] = '\0';
nbytes_read=recv(sclient,(char *)date,sizeof(date),0);
if(nbytes_read > 0){
printf("Date: %s (%i)\n",date,nbytes_read);
//cout.flush();
nbytes_read=recv(sclient,(char *)name,sizeof(name),0);
if(nbytes_read > 0){
printf("Name: %s (%i)\n",name,nbytes_read);
//cout.flush();
nbytes_read=recv(sclient,(char *)buf,sizeof(buf),0);
strcpy(text,buf);
while(nbytes_read > 0){
nbytes_read=recv(sclient(char*)buf,sizeof(buf),0);
strcat(text,buf);
}
}
}
printf("Date: %s. Name: %s. Text: %s\n",date,name,text);
Here's a simple "receive all" function:
int recv_all(int sockfd, void *buf, size_t len, int flags)
{
size_t toread = len;
char *bufptr = (char*) buf;
while (toread > 0)
{
ssize_t rsz = recv(sockfd, bufptr, toread, flags);
if (rsz <= 0)
return rsz; /* Error or other end closed cnnection */
toread -= rsz; /* Read less next time */
bufptr += rsz; /* Next buffer position to read into */
}
return len;
}
One (repeated) mistake is:
nbytes_read=recv(sclient,(char *)date,sizeof(date),0);
recv() does not null terminate. This means date will not have a null terminator if sizeof(date) bytes is read. This is a problem when a non-null terminated string is passed as an argument to printf() with "%s" format specifier. If the string is non-null terminated you may see garbage characters appearing after the actual string data. You need to read one less than the target buffer and null terminate or use the format specifier "%*.s" that does not require null termination:
printf("%.*s", n, s); /* Prints first 'n' bytes from 's'. */
Note you can initialise a char[] to all nulls instead of using a for:
char date[8] = "";
or you can use memset().
Adding to #hmjd's find:
declared at the var decls is your text pointer...
char * text;
then later...
strcpy(text,buf);
while(nbytes_read > 0){
nbytes_read=recv(sclient(char*)buf,sizeof(buf),0);
strcat(text,buf);
}
Maybe try setting that 'text' pointer to something beside a random stack value will help as well.
Continuing the barrage, though the following will not necessarily blow up, your date variable as:
char date[8];
on both client and server side The client variable isn't used at all. The server variable, however is:
nbytes_read=recv(sclient,(char *)date,sizeof(date),0);
if(nbytes_read > 0){
Problem is, the date you sent is, in fact, 8 chars wide already: "12/10/12". Therefore, even if you firm-up a null terminator on the end of your string, which you should always do regardless (good practice):
date[ sizeof(date)/sizeof(date[0])-1 ] = 0;
you'll be truncating off the last char of your date.
There are other things wrong with this; we've only pointed out a few. Think about sending length-prefixes with each of these data values in the array, with checks or range to ensure you get what you expected.
Finally, spending some time on the business-end of a debugger would probably do you very well, especially on the server side.

Concatenating multiple strings?

I am processing an input string, which consists of a process name, followed by an arbitrary amount of arguments.
I need the process name , along with all of the arguments, in one string.
I thought I could use strcat in a loop, so that it cycles through all of the args and each time appends the arg to the string, but I am having problems with getting a string that in empty to begin the loop.
Can anyone help me out with some basic code?
Thanks.
EDIT:
I'm posting my code for clarity. Mike's post is closest to what I have now:
char * temp;
strcpy(temp,"");
for (i = 4; i < argc-1; i++) // last arg is null, so we need argc-1
{
strcat(temp,argv[i]);
strcat(temp," ");
}
ignore the 4 in my for loop for the moment (magic number, i know.)
I am getting a segfault with this code. Is it because of my string assignment? I assume that is the case and hence I asked the question of how i could combine the strings.
Let's say your input strings are in an array of char pointers, suggestively called argv, of length argc.
We first need to determine how much space is needed for the output:
int length = 0;
for (int i = 0; i < argc; ++i)
length += strlen(argv[i]);
Then we allocate it, adding an extra char for the '\0' terminator:
char *output = (char*)malloc(length + 1);
Finally, the concatenation:
char *dest = output;
for (int i = 0; i < argc; ++i) {
char *src = argv[i];
while (*src)
*dest++ = *src++;
}
*dest = '\0';
Note that I don't use strcat here. Reason is that this sets us up for a Schlemiel the Painter's algorithm: for each iteration, the entire output string would be scanned to find its end, resulting in quadratic running time.
Don't forget to free the output string when you're done:
free(output);
I'm a bit tired so I may be overlooking something here. A better solution, using standard library functions, is welcome. It would be convenient if strcat returned a pointer to the terminator byte in dest, but alas.
You want an empty C string? Is this what you are looking for: char p[] = "";?
UPDATE
After you posted some code it is clear that you have forgotten to allocate the buffer temp. Simply run around the arguments first, counting up the length required (using strlen), and then allocate temp. Don't forget space for the zero terminator!
You could provide the "arbitrary amount of arguments" as one argument, ie an array/list, then do this pseudocode:
str = "";
i = 0;
while i < length of input
{
str = strcat ( str , input[i]);
i++;
}
#include<stdio.h>
#include<stdarg.h>
int main(int argc, char** argv) {
// the main parameters are the same situation you described
// calling this program with main.exe asdf 123 fdsa, the program prints out: asdf123fdsa
int lengths[argc];
int sum =0;
int i;
for(i=1; i<argc; i++) { // starting with 1 because first arg is program-path
int len = strlen(argv[i]);
lengths[i] = len;
sum+=len;
}
char* all = malloc(sum+1);
char* writer = all;
for(i=1; i<argc; i++) {
memcpy(writer, argv[i], lengths[i]);
writer+=lengths[i];
}
*writer = '\0';
printf("%s\n", all);
system("pause");
return 0;
}
A string in C is represented by an array of characters that is terminated by an "null" character, '\0' which has the value 0. This lets all string functions know where the end of a string is. Here's an exploration of different ways to declare an empty string, and what they mean.
The usual way of getting an empty string would be
char* emptyString = "";
However, emptyString now points to a string literal, which cannot be modified. If you then want to concatenate to an empty string in your loop, you have to declare it as an array when you initialize.
char buffer[] = "";
This gives you an array of size one. I.e. buffer[0] is 0. But you want an array to concatenate to- it has to be large enough to accomodate the strings. So if you have a string buffer of certain size, you can initialize it to be empty like so:
char buffer[256] = "";
The string at buffer is now "an empty string". What it contains, is buffer[0] is 0 and the rest of the entries of the buffer might be garbage, but those will be filled once you concatenate your other strings.
Unfortunately, the problem with C, is you can never have an "infinite" string, where you are safe to keep concatenating to, you have to know it's definite size from the start. If your array of arguments are also strings, you can find their length using strlen. This gives you the length of a string, without the null character. Once you know the lengths of all your sub-strings, you will now know how long your final buffer will be.
int totalSize; // assume this holds the size of your final concatenated string
// Allocate enough memory for the string. the +1 is for the null terminator
char* buffer = malloc(sizeof(char) * (totalSize + 1));
buffer[0] = 0; // The string is now seen as empty.
After this, you are free to concatenate your strings using strcat.

Resources