Encrypt a message in C - c

I have to write a function to encrypt a message given as a string input using the given encryption key. The function should output the encrypted message as a string to encryptedMessage in the argument list. The function prototype must be as follows: void encryptMessage(char *encryptedMessage, char *message, char *encryptionKey); The function must take the encryption key and convert each of its characters, which represent hexadecimal digits, to their equivalent decimal values as integers. I already wrote a function to convert hex2decimal. The message must then be encrypted by adding the first of these integer values to the ASCII value of the first character in the message, and the second of the integer values to the second character in the message, and so on, and start again with the first integer value after every 16. This will be necessary if the message is longer than the encryption key, which will usually be the case.
here is some of my code so far:
void encryptMessage(char *encryptedMessage, char *message, char *encryptionKey)
{
int *arr = malloc(sizeof(int)*getStringLength(encryptionKey));
int i;
for(i = 0;i < getStringLength(encryptionKey);i++){
arr[i] = hexDigit2Dec(encryptionKey[i]);
message[i] = message[i] + (char)arr[i];
if(getStringLength(message ) > getStringLength(encryptionKey)){
i = 0;
}
}
free(arr);
}
when i run it "project.exe has stopped" pops up. Please help me out, i am new at C and struggling a lot.

You need 2 counters: one for the encryption key position and one for the character being worked on.
You are using one and resetting it to zero whenever the message gets longer than the key causing an infinite loop
for ( keyPos = 0, msgPos = 0; msgPos < getStringLength(message ); ++keyPos, ++msgPos )
{
// calculate and append next char to encrypted message here
if ( keyPos >= getStringLength(encryptionKey)
{
keyPos = 0;
}
}

You'll have to learn to do some planning first and think about what you need to do ... I'll try to give kind of a step by step coding here so hopefully you will see where you went wrong.
But first, there's a standard C function for getting the length of a string: strlen(). I will use this. If you have certain requirements to use something different instead, oh well.
Let's start with the prototype you were given:
void encryptMessage(char *encryptedMessage, char *message, char *encryptionKey)
{
It's a bit ambiguous, but I guess encryptedMessage should be the output. For a real-world project, make it explicit by adding a const to the other pointers. But for now, let's ignore that. As encryptedMessage is a parameter here and not the return value, I assume it's the callers responsibility to provide storage. So, move on ...
You will need the length of your encryptionKey multiple times, let's put it in a variable:
size_t keyLen = strlen(encryptionKey);
And then you need the integer values of the key hex digits multiple times, too, so let's pre-calculate them:
char *keyDigits = malloc(keyLen); // we only need char-sized integers here
for (int i = 0; i < keyLen; ++i)
{
keyDigits[i] = (char)hexDigit2Dec(encryptionKey[i]);
}
Now it's time for the main loop ... you just need to take each character of message and add a value from keyDigits to it:
int keyPos = 0;
for (int i = 0; i < strlen(message); ++i)
{
encryptedMessage[i] = message[i] + keyDigits[keyPos];
if (++keyPos == keyLen) keyPos = 0;
}
And that's it ... free your temporary array and you're done.
free(keyDigits);
}

Related

decrypt/encrypt xor algorithm in C

Here, I'm trying to encrypt a message using XOR. However, when I run the program, I'm getting weird output (random outputs). I guess I'm missing something here.
my sample of code:
/*
* Description: Decipher the message using XOR and print it.
* Parameters:
* cipher: The cipher of the message (With the key embedded at the start)
* keyLength: The length of the key at the start of the message
*Return:
* None.
*Note:
Do not use any additional variables for this challenge.
*/
void print_cipher_message(unsigned char cipher[], int keyLength) {
// TODO: complete the function
//keyLength = 3;
for (int i = 0; i < strlen(cipher) && i <= keyLength; i++) {
i % keyLength;
cipher[i] = cipher[i] ^ keyLength;
// i% keyLength;// i % ;//cipher[i] % sizeof(keyLength);
printf("%c", cipher);
}
}
int main() {
unsigned char cipher[] = "\x12\x56\xd4\x61\x26\xbb\x7b\x3a\xbd\x7c\x31\xf4\x61\x3e\xbb\x65\x25\xf4\x7b\x25\xf4\x73\x76\x97\x40\x1f\x99\x57";
int keyLength = 3;
//print the cipher message
print_cipher_message(cipher, keyLength);
return 0;
}
The expecting result is as the following:
/*
EXAMPLE:
cipher="\x31\xf4\x61\x7a\x33\xb8\x7e\x39\xf4\x65\x39\xa6\x7e\x32\xf5\x33"
keyLength=3;
then the cipher is:
"\x31\xf4\x61\x7a\x33\xb8\x7e\x39\xf4\x65\x39\xa6\x7e\x32\xf5\x33"
^----Key-----^^-------------------Message------------------------^
*/
I Would appreciate your help. Thank you.
A couple of problems I see right away:
You're asking printf to print a char (%c) but are passing a pointer to char instead of a char.
There's a line i % keyLength that doesn't do anything, it just performs a calculation and discards the results.
Also you're calling strlen every time through the loop, which is going to be kind of expensive.
I think what you're expected to do here is have two indexes, one that loops over the range 0 to keyLength, and another that iterates over the string to encode (starting at index keyLength). The function ends when the second index reaches the end of the string.
At first, you need to understand question correctly. Your question states that key is embedded at start of your cipher and its length is keyLength. So you need to separate this part and xor it with the rest of cipher.
Code should be similar to this:
void print_cipher_message(unsigned char cipher[], int keyLength) {
for (int i = 0; i < strlen((char*)cipher) - keyLength; i++) {
cipher[i + keyLength] = cipher[i + keyLength] ^ cipher[i % keyLength];
}
printf("%s", cipher + keyLength);
}
I wrote it off top of head quickly without debugging, so it may have bugs. In addition, question is not correct itself. it needs length of cipher and we cannot really use strlen() for it.

C- Find array length from pointer

So I've got this here:
#include <stdio.h>
char halloString[] = "Ha::ll::o";
char perfumeString[] = "47::11";
char veryLongString[] = "47::11::GHesd::dghsr::bfdr:hfgd46dG";
char *extract (char *input) {somethinghappenshere}
where extract needs to get all characters after the last double ":" of given input:
"o" for halloString
"11" for perfumeString
"bfdr:hfgd46dG" for veryLongString
In short, my issue is finding the length of the string *input points to. As far as I understand it that won't be happening without making something really sketchy.
Am I correct in assuming the length cannot be acquired in a good way?
And if so would it be a horrible idea to do, for example:
char stringToProcessTemp1[50];
char stringToProcessTemp2[50];
char stringToProcess[50];
for (int i = 0; i < 50; i++) {
stringToProcessTemp1[i] = input + i;
}
for (int i = 0; i < 50; i++) {
stringToProcessTemp2[i] = input + i;
}
for (int i = 0; i < 50; i++) {
if (stringToProcessTemp1[i] == stringToProcessTemp2[i]) {
stringToProcessTemp[i] = stringToProcessTemp1[i];
}
}
Later checking where the first empty index is and saving everything before it as the used String as from my very limited experience in C when you go outside of an array you tend to get different outputs every time therefore making the chance both Temp strings match for an extra element directly after the last one of the original string what I'd consider low enough.
It's honestly the only idea I've got right now.
Finding the length of a string is no problem. strlen will do that for you. However, you don't even need that.
You can use the strstr function to find a substring within a string, in this case "::". When you find one, keep looking right after the last one you found until you don't find it anymore, then the last one you found is the one you want. Then you want the substring that starts right after it.
char *extract(char *input)
{
char *last = NULL, *start = input, *curr;
while ((curr == strstr(start, "::")) != NULL) {
last = curr; // keep track of the last "::" found
start = last + 1; // move the starting string to right after the last "::"
// move up 1 instead of 2 in case of ":::"
}
if (last != NULL) {
last +=2; // We found one; move just past the "::"
}
return last;
}
C strings, which are really only an array of characters, are by definition terminated by '\0'. So, for a well formed C string you can always get the length of the string by using strlen().
If, however, your string is not null-terminated, there is no way to determine it's length, and it is not a C string by definition any more, but just an array of characters.

Why doesn't the encryption function 'crypt()' accept my nonce although the nonce is a valid, two characters long string?

I want my program to extract the first two characters of the given hash hash. These first two characters represent a nonce/salt that the password was encrypted with (DES-based, crypt() function). The first two characters of hash are stored in the array nonceAsArray[], which is being passed down to the function concatenateCharacters(), whose job is to turn these characters into a nonce of type string and save it in the variable nonce so that it can be used later on in order to encrypt a password.
The function seems to concatenate the two characters perfectly fine. However, when nonce is given to the crypt() function as an argument, it returns null but only, if I calculate both, generatedHash1 and generatedHash2:
Output:
generatedHash1: 14dJperBYV6zU
generatedHash2: (null)
However, when I exclude the calculation of the first hash string generatedHash1 = crypt("myPassword", "14");, my program outputs the following:
generatedHash2: dJperBYV6zU
The crypt() function now seems to have accepted the value that is being stored in nonce. Another odd thing is that crypt() returns a hash without the nonce being represented in the first two characters of generatedHash2. The encrypted password however should be 13 characters long in total.
Fired up the debugger and checked the values that are being stored in nonce. I stumbled upon this:
nonce: 0x7fffffffdd40 "14"
and
*nonce: 49 '1'
I assume that the first part that starts with 0x7f... is the memmory address and next to it the value that stored at this address.
Can anyone help me understand as to why the crypt() function doesn't seem to accept the value in nonce? I would greatly appreciate if anyone could give me a hint where to look or an explenation as to why it fails.
(...)
#include <cs50.h>
#include <string.h>
(...)
// extract the first two characters of 'hash' (== nonce/salt)
string hash = "14dJperBYV6zU";
char nonceAsArray[2];
for (int i = 0; i < 2; i++)
{
nonceAsArray[i] = hash[i];
}
string nonce = concatenateCharacters(nonceAsArray, 2);
printf("first hash: %s\n", crypt("myPassword", "14"));
printf("second hash: %s\n", crypt("myPassword", nonce));
// connects characters to strings
string concatenateCharacters(char characters[], int arraySize)
{
char terminator[1] = {'\0'};
// create array that can store the password and to which the terminator can be appended (hence +1)
char bigEnoughArray[arraySize + 1];
for (int i = 0; i < arraySize; i++)
{
bigEnoughArray[i] = characters[i];
}
return strcat(bigEnoughArray, terminator);
}
I "guess" it helps to replace this
string hash = "14dJperBYV6zU";
char nonceAsArray[2];
for (int i = 0; i < 2; i++)
{
nonceAsArray[i] = hash[i];
}
string nonce = concatenateCharacters(nonceAsArray, 2);
by
#define NONCE_MAX (2);
string hash = "14dJperBYV6zU";
char nonceAsArray[NONCE_MAX + 1] = ""; /* zeros out all nonceAsArray */
strncpy(nonceAsArray, hash, NONCE_MAX);
string nonce = nonceAsArray;

Can't figure out hexadecimal conversion with pointers in C

So I am getting pretty frustrated with this and feel the only way to figure out exactly what I am doing wrong is to ask you fine people. I am trying to convert a string of characters (contains number values) to hexadecimal. Here is my code (note, I haven't placed the switch for 10-15 to letters yet; I just wanted to make sure I was getting back integer values when I ran this... no luck):
void toHex(char *inString){
char *charVal = inString;
char decVal[100];
for(int i = 0; decVal[i] != '\0'; i++){
decVal[i] = *charVal;
charVal++;
}
char storeMod[100];
int i = 0;
int testVal = atoi(decVal);
for(i; testVal >= 16; i++){
int a = testVal;
testVal = testVal/16;
storeMod[i] = a;
}
int a = 0;
char hexval[100];
hexVal[0] = '0';
hexVal[1] = 'x';
for(int j = i+2; j>=2; j--){
hexVal[j] = storeMod[a];
a++;
}
printf("%s hex valu\n", hexVal);
return;
}
For example, an input of 300 returns ,#
I have also tried:
char hexVal[100];
sprintf(hexVal,"%x",*inString);
strcpy(instring,hexVal);
which returns a hex value of 3fa844e0 for 300 which is obviously wrong as well. Any help is appreciated, I need to do this for octals too so I have to figure this concept out and see what I am doing wrong.
Instead of:
sprintf(hexVal,"%x",*inString);
Use:
sprintf(hexVal, "%x", atoi(inString));
As has been pointed out, you can replace your whole function with:
printf("%lx\n", strtol(inString, NULL, 10));
But, if this is for school or personal gratification, you seem to know the two main steps.
Convert the string to an integer
Encode the integer back into a string of the right base.
For step one, step through the number left-to-right (which is easy in a string) multiplying a running result by 10, and adding the current digit.
For step two, simply run through the number four bits(one hex digit) at a time, inserting that plus '0'. If you've started from the LSB, remember to reverse the string.

How to XOR scramble a string in C and back again with the same function?

I am trying to obfuscate a string in a program. Currently, I only have a simple string reversal working. I would like to be able to perform XOR scrambling on the data to make it much more secure, however the method I have tried is not working.
The same function and input type is used to decode the string. This is no problem with string reversal, as it just reverses back, but can this be done easily with XORing without getting too complex? I would prefer if the process kept just the one string, like the reversal does. Here is my reversal function.
void reverse_string(unsigned char *buf, int length)
{
int i;
unsigned char temp;
for (i = 0; i < length / 2; i++)
{
temp = buf[i];
buf[i] = buf[length - i - 1];
buf[length - i - 1] = temp;
}
}
And here is the attempt at a XOR function
void charxor(char * text, int len) {
const unsigned char enc[8]={173,135,131,121,110,119,187,143};
char ch;
int i;
int ind=0;
for (i=0;i<len;i++) {
ch=*text++;
if (ch)
*text = ch ^ enc[ind++];
ind %=8;
}
}
Can anyone help? Would be much appreciated!
You seem to be overcomplicating things a bit. Try this instead:
void charxor (unsigned char *text, int len) {
const unsigned char enc[8] = {173,135,131,121,110,119,187,143};
int i;
for (i = 0; i < len; i++) {
text[i] ^= enc[i % 8];
}
}
Note that the XOR operation can introduce null chars into the string, so you really do need to keep track of its length instead of just relying on the presence of a trailing null char.
Also keep in mind that, while this may indeed be relatively speaking "much more secure" than just reversing the string, any reasonably clever person with access to enough samples of the output can probably figure out how to decode it in around fifteen minutes or so.
this is a pbox, it would require you to make a non repeating integer key - random - same size as said block. the last block would start with the offset which could be just random data. Doesn't cover null terminators so decide where the data is going / what your doing with it. you could realloc(buff, "A") to use memmove. make 3 64 bit boxes, and a subset of 16 4 bit boxes from the output of the 64 and it starts to look like a poor implementation of des, which openssl has build into it. The fundamental advantage is being able to encrypt/decrypt with the same function / address space. This could also allow you to encrypt in place without a extra buffer. KSZ is the length of your block(s)/key
char
*zecr
(bff, zbf, ky, ze)
char *bff;
char *zbf;
unsigned int ky[];
short ze;
{
/* main encrypt decrypt function */
int i=0;
while( i < KSZ ) {
int dx = ky[i];
if( ze == 1 ) { // encrypt
char c = bff[dx];
sprintf(zbf + i, "%c", c);
} else { // decrypt
char c = bff[i];
char tk[1] = "";
sprintf(tk, "%c", c);
memmove(zbf +dx, tk, 1);
}
i++;
}
return zbf;
}
xoring is a binary operation, which will yield vastly different results depending on how you cast it. You got the right idea using ocdec but if the idea is to keep it simple im going to assume you don't actually know assembly despite the requested reference, stick with c calls its simpler for how you are most likely going to be using the data.
-the female orgasm, that's the myth. -SUN TZU

Resources