Decrypting opened textfile with unknown key using ASCII in C Caesar Cipher - c

So I was wondering how I could decrypt an encrypted textfile that is opened through a command line argument using ASCII and with an unknown key and then printing it all out and with the answer key. I seem to have been able to actually print out the encrypted message but don't have a clue on how to determine how to find the key and print it out.
int main( int argc, char *argv[]) {
FILE *fp = stdin; // defaults
int n = 13;
int shift;
// process command line
switch (argc) {
default:
fp = fopen(argv[1], "r"); // should check for problems
n = atoi(argv[2]);
break;
}
// rotate text
int c, key;
int i;
while( (c = fgetc(fp)) != EOF) {
// This is where I have managed to make C an integer
// and print out the encrypted message using the printf function.

Usually, decryption without knowing the key is impossible. Luckily, your message is encrypted with one of the simplest methods possible...
Caesar cipher encryption works like so:
* Choose offset K
* For every letter in message do
** Letter = Letter+K
So if we wanted to break that code, we could just go over all possible values of K (255) and rule out every possibility that generates ASCII codes that are not letters or numbers (assuming the original message is in plain English).
You might still need some user interaction to decide if there is more than one option, but the options will be limited.

Related

parsing text file of unknown size to array in c

i'm new programmer in c and need some help. I'm trying to read text file which contains numbers (long doubles) separated by ','. My problem is that I don't know what is the size of each line and every solution I find online assume it's size. This is a part of work I got to do and I can't use scanf/fscanf. finally I would like to have array contains the numbers (without the ','), what is the best way to do it?
Thanks a lot!
edited:
FILE *inputFile;
inputFile = fopen("C:\\Users\\studies\\C\\Exe1\\input_example.txt",
"r");
for (int c = 0; c < 7; c++) {
fscanf(inputFile, "%Lf,", &params[c]);
}
any other way I tried to read just didn't go well, fgets, getchar, etc..
Divide and conquer! See if you're able to read the file correctly without storing anything. Just read and print what you read, so you can compare your output with the input file. If they match, you're on your way.
It's easier than you think to read the file. Use a char array as a temporary buffer for each number and read the file character by into the buffer. If the input is a ',' then you have read a complete number. Same goes for the newline '\n'.
// untested snippet
char buf[1024]; // Make it big
size_t i = 0;
int c;
long double d;
while ((c = fgetc(fp)) != EOF) {
if (c == ',' || c == '\n') {
buf[i] = '\0';
d = strtold(buf);
printf("%lf%c", d, c); // debugging, sanity check
i = 0;
}
else
buf[i++] = c;
}
There may be uncovered corner cases which the snippet doesn't cover, like missing newline at end of file, or silly Windows \r\n combos. Also, string to double conversion needs proper error checking. Still, the snippet should get you going.

Assembly Vigenère cipher program

I'm not really sure how to approach this problem:
For better frequency characteristics the keyword should not have any repeated
letters. Also, if it contains the letter A the encrypted letter will be the same as the plaintext, although this is not necessarily a bad thing.
To implement this algorithm with a pencil and paper, many descriptions ask you tobuild a Vigenère Square. However this is not really necessary when you are using acomputer to do the encoding and decoding.
Essentially the keyword is written repeatedly over and over above the plaintext.
Suppose the keyword is CRYPTOGRAM.
CRYPTOGRAMCRYPTOGRAMCRYPTOGRAMCRYPTOGRAMCRYPTOGRAMCRYPTOGRAMCRYPTOGR
WEHAVEBEENBETRAYEDALLISDISCOVEREDFLYATONCEMEETUSBYTHEOLDTREEATNINEPM
Consider that the letters are numbered 0 to 25. The letter on the top determines
which Caesar-cypher to use for the letter below. Thus C means shift the alphabet by 2, A means shift by 0, and so on. In mathematical terms, we are adding the two letters together modulo 26. (The square was used because the concept of modular arithmetic was not generally understood by soldiers in 1553.)
To decrypt the message, the same operation is performed in reverse. That is, the
value of the keyword letter is subtracted rather than added. Step 3. What your code should do
Your code should use STDIN and STDOUT for input and output. (This is the
default.) Use redirection on the command line to read from a file and write to a
file.
Your code should open a file, read it character by character and save it into an
array.
When you get to the end of the file you should encode the contents of the
array with a Vigenère cipher using the keyword CRYPTOGRAM, then print it
out.
Maintain the distinction between upper-case and lower-case letters, and do
not modify non-alphabetic characters. This is not very good for the security of
your message, but the result will look neater.
This program should use glibc functions. In addition to printf(), you may
need getchar() and putchar().
Assume that the input file contains just ASCII text Don't worry about what
happens with non-text files.
Once the encoder is working, build a decoder by duplicating the code and
changing the addition to a subtraction.
If you use printf() to output the array, remember that a null termination is
required on a string.
Start by breaking the problem down in smaller parts like "read input from stdin", "encrypt a string", "print output to stdout".
You need to be familiar with the modulus operator, because you will need to use it more than once in your program.
If you are having a hard time, here is one way to break down the problem
(there are other ways that are just as good):
/* For printf, getchar etc: */
#include <stdio.h>
/* For isalpha, isupper, islower etc: */
#include <ctype.h>
char encryptChar(char ch, char cypher) {
int shiftBy = cypher - 'A';
char encryptedLetter;
/* There are 3 cases: uppercase, lowercase, other char */
if (isupper(ch)) {
/* add code to encrypt uppercase char */
} else if (islower(ch)) {
/* add code to encrypt lowercase char */
} else {
/* Other characters stay as they are */
encryptedLetter = ch;
}
return encryptedLetter;
}
char *cypherString = "CRYPTOGRAM";
int main(int argc, char **argv) {
int ch;
int cypherStringLength = strlen(cypherString);
int counter = 0;
char cypher;
while ((ch = getchar()) != EOF) {
cypher = cypherString[counter%cypherStringLength];
ch = encryptChar(ch, cypher);
/* Add code to print the character */
counter++;
}
return 0;
}

File in c language

I need help about my code, I got some works, and it is one of the assignments.
suppose an encrypted file was created using the encoding/decoding scheme.
Each letter is substituted by some other letter according to a given mapping as shown below.
char * letters = "abcdefghijklmnopqrstuvwxyz";
char * enc = "kngcadsxbvfhjtiumylzqropwe";
For example, every a becomes a k when encoding a text, and every k becomes an a when decoding.
You will write a program, encode or decode a File, and then encodes or decodes the File using the mapping above.
Capital letters are mapped the same way as the lower case letters above, but remain capitalized.
For example, every 'A' becomes 'K' when encoding a file, and every 'K' becomes an 'A' when decoding.
Numbers and other characters are not encoded and remain the same.
Write a program to read a file and encode the file to an encrypted file.
And write a program to get an encrypted file and decode to original file.
Your program should prompt the user to enter an input file name and an output file name.
Ask for input file name/ output file name (encrypted file). The encrypt using above encode/decode.
Ask for encrypted file and decoded to original input file.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
int main()
{
char letters[]={"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"};
char enlet[]={"kngcadsxbvfhjtiumylzqropweKNGCADSXBVFHJTIUMYLZQROPWE"};
char infile[20];
char outfile[20];
char ch;
int i;
FILE *org, * enc, *dec;
printf("Enter file name (***.txt) : ");
gets(infile);
printf("Enter saving file name (***.txt) : ");
gets(outfile);
org = fopen(infile,"r");
enc = fopen(outfile,"w+");
while((ch=fgetc(org))!=EOF)
{
for(i=0;i<52;i++)
{
if(letters[i]==ch)
{
ch=enlet[i];
}
}
fputc(ch,enc);
}
fclose(org);
fclose(enc);
return 0;
}
this code is working but letters doesn't change correctly.
If there are "abcdefghijklmnopqrstuvwxyz" in my original file,
then, it happens "felcadlpbrfhjeiqmwleqropwe" in encoded file.
I expected it would be "kngcadsxbvfhjtiumylzqropwe"
I don't know what are the errors in my code.
Your if block should read:
if ( letters[i]==ch )
{
ch = enlet[i];
break;
}
so that ch is not replaced twice. I.e., the moment you know the substitution for that input file position, break, and move on.
Inside this loop, you overwrite ch after it has been replaced.
while((ch=fgetc(org))!=EOF)
{
for(i=0;i<52;i++)
{
if(letters[i]==ch)
{
ch=enlet[i];
}
}
fputc(ch,enc);
}
You could do one of two things:
Instead of assigning ch=enlet[i] just do the fputch(enlet[i])
or
Do break the loop as soon as you found a match
You could skip the for() loop and just use:
if( org && enc )
while( (ch=fgetc(org))!=EOF)
{
char *p = strchr( letters, ch );
fputc( (p)?enlet[p-letters]:ch, enc );
}
Also, you really should declare ch as an int to compare it to EOF. And gets() is a buffer overflow waiting to happen and crash your program / provide a security exploit hook (use fgets() and remember to parse off the trailing newlines). And you never check to see if org and enc aren't NULL (files opened successfully)

Implementation of a Stream cipher in c

I want to implement the following function:
I am using the Mersenne-Twister-Algorithm (from Wikipedia) as my pseudorandom number generator.
It is a stream cipher
The pseudocode is: encrypted text = CLEARTEXT XOR STREAM; the 'stream' is defined as PSEUDORANDOM_NUMBER XOR KEY
I wrote the following function:
int encrypt(char clear[1000], char key[100], int lk/*length of the cleatext*/, int ls /*length of key*/) {
int a, i;
unsigned char result[1000];
char string[1000];
for (i = 0; i <= lk; i++) {
if (i+1-ls >= 0) { /*if the key is too short*/
a = mersenne_twister();
string[i]=key[i+1-ls]^a; /*XOR */
} else {
a=mersenne_twister();
string[i] = key[i]^a; /*XOR */
}
result[i] = clear[i]^string[i];
putchar(result[i]);
}
return 1;
}
But the function does not work properly; it returns (the putchar part) something that is not readable.
Where is my mistake? Or is the whole code wrong?
If you are trying to print a char xored with something else, you will really often get strange characters. For instance, xoring 'M' with 'P' will result in '\GS' (Group Separator character), which is not printable.
Don't print the result as a character. It's not a character: you've XOR'd a character with some pseudo-random byte. The result is a byte. It may, by chance, be printable, but, then again, it may not be. You should treat the result for what it is, a byte, and print it as such:
/* format a byte as 2 hex digits */
printf("%02X", result[i]);
I will also add a cautionary note: do not use this "cipher". The Mersenne twister is not a cryptographically secure random number generator and the resulting cipher won't be secure either.
If you want to study stream ciphers, start with the simple Vernam cipher then read about RC4. Both are easy to understand and simple to implement. As a result they are good for getting your feet wet so to speak.

Adaptation problem with the Blowfish Encryption in C

I'm writing a program that implements the Boneh-Franklin Identity Based Encryption. For the actual encryption methods, I use Blowfish which I got from (https://voltar.org/). I'm trying to adapt the blowfish encryption/decryption code to my program. The difference in my program is that I read the message from the standard input, encrypt it and print the encryption, then decrypt it and print the decryption (which should be the original message). Currently, I read the input message up to a "?" character and then try to follow the code from the site. However, the decryption is printed as unreadable characters. I tried to solve this problem but I got stuck. Can you please help me?
//initializations
BF_KEY s_key; //shared key of the blowfish encryption
char plain[1000000]; //the plaintext of the message
char cipher[1000000]; //the ciphertext of the message
char byte; //to hold the byte of the msg
char *token; //points to tokens of the msg
char IV[8]="MY*IV000"; //the initialization vector
int offset = 0; //the offset of encryption
int b_count = 0; //number of bytes in d_buf
char block[8]; //blocks of encryption
char msg[1000000]; //the input msg from the user
int j; //used to read input in a loop with getchar
int i; //for-loop value
int len; //used to calculate lengths different variables
int f; //flag for the setup stage
int q; //used to read input in a loop with getchar
q=0; //reset the index reader
char in; //to read characters
printf("Please enter the message you wish to send:\n");
************ This is my code to read the input message: ***************
//this loop reads the input from the user since C does not
//provide a safe function to read strings with white spaces
while (in != '?'){
in=getchar();
if(in != '?') //dont include the delim character in the string
msg[q++]=in;
}
msg[q]='\0'; //truncate the string by the null character
************ Then I used the code (cited and referenced) for encryption ***************
Of course I modified it as message read from stdin not program args
for(i=0; i<strlen(msg); i++) //copy the input message to plain
plain[i] = msg[i];
//set up the shared key of the BF encryption
BF_set_key(&s_key, strlen(ekey_buf), ekey_buf);
while(1){
for(i=0; i<8; i++) //reinitiate the block of 8 characters each time
block[i] = 0;
strncpy(block, plain+offset, 8);
BF_cbc_encrypt(plain+offset, cipher, 8, &s_key, IV, BF_ENCRYPT);
for(i=0; i<strlen(cipher); i++){
printf("%02x", (unsigned char) cipher[i]);
}
if( strlen(plain+offset)>8 ){ //if there is still more characters
offset += 8; //process the next block of 8 characters
} else
break;
}
//the cipher is correctly printed
************ Then I used the code (cited and referenced) for decryption ***************
Here, I excluded the part where it tokenized the cipher and created the plain char array for decryption, I simply passed the cipher array to be decrypted (as it is output from the encryption function), and stored in the plain char array with length = strlen(cipher)
//set up the shared key of the BF encryption
BF_set_key(&s_key, strlen(dkey_buf), dkey_buf);
BF_cbc_encrypt(cipher, plain, strlen(cipher), &s_key, IV, BF_DECRYPT);
printf("plain after decryption: %s\n", plain);
//HERE IS THE PROBLEM: I get unreadable characters as output of this line
Any help is appreciated. Sorry for the inconvenience and many thanks in advance.
I have a hunch it's a dirty IV, but it's just a guess.
for(i=0; i<8; i++) ivec[i] = 'i';
BF_cbc_encrypt(inputz, outputz, strlen(inputz), &key, ivec, BF_ENCRYPT);
// won't decrypt right:
BF_cbc_encrypt(inputz, outputz, strlen(inputz), &key, ivec, BF_DECRYPT);
// without resetting the ivec to all 'i's, the decryption will fail.
// This would work though:
for(i=0; i<8; i++) ivec[i] = 'i';
BF_cbc_encrypt(inputz, outputz, strlen(inputz), &key, ivec, BF_ENCRYPT);
for(i=0; i<8; i++) ivec[i] = 'i';
BF_cbc_encrypt(inputz, outputz, strlen(inputz), &key, ivec, BF_DECRYPT);
My guess is only correct if every block after the first decrypts correctly though.
Another big problem with strlen(inputz) is that if the strlen() doesn't fall exactly on an 8byte boundary, your decrypt will ultimately fail. I have addressed the problem rather completely as a gist on github.
Check your encoding.
You need to null terminate plain i.e. something like plain[ strlen(dkey_buf) ] = 0 is needed.
Aren't there patent restrictions on using/distributing programs that leverage the IBE algorithm?

Resources