tags:

views:

16

answers:

3

Hi,

I have a plain text and I have the cipher text with me and my task is to find the key for the cipher text declared. The key is a word list like a dictionary. I have written the code in c and it compiles perfect and creates the file with all the ciphers. The problem I am facing is that every time i run the code a cipher text is completely different. I have no clue where I am making a mistake. The following is the code I had written

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <openssl/evp.h>

int main()
{
  int i;
  char words[32], t;
  FILE *key, *outFile;
  const char *out = "Output.txt";
  unsigned char outbuf[1024 + EVP_MAX_BLOCK_LENGTH];
  unsigned char iv[] = "0000000000000000";
  int outlen, tmplen;
  int num;
  EVP_CIPHER_CTX ctx;
  EVP_CIPHER_CTX_init(&ctx);
  char inText[] = "This is a top secret.";
  char cipherText[] = "8d20e5056a8d24d0462ce74e4904c1b513e10d1df4a2ef2ad4540fae1ca0aaf9";
  key = fopen("words.txt", "r");
  if( remove("ciphertext.txt") == -1 ) {
    perror("Error deleting file");
  }
  outFile = fopen("ciphertext.txt", "a+");
  if( key < 0 || outFile < 0 )
    {
      perror ("Cannot open file");
      exit(1);
    }

  char pbuffer[1024];


  while ( fgets(words,32, key) )
    { 
      i=strlen(words);
      words[i-1]='\0';
      //printf("%s",words);
      i = 0;
      EVP_EncryptInit_ex(&ctx, EVP_aes_128_cbc(), NULL, words, iv);
      if(!EVP_EncryptUpdate(&ctx, outbuf, &outlen, inText, strlen(inText)))
        {
          EVP_CIPHER_CTX_cleanup(&ctx);
          return 0;
        }
      if(!EVP_EncryptFinal_ex(&ctx, outbuf + outlen, &tmplen))
        {
          EVP_CIPHER_CTX_cleanup(&ctx);
          return 0;
        }
      outlen += tmplen;
      print_hex(outbuf, outlen, outFile);
    }
  fclose(key);
  fclose(outFile);
  return 1;
}

int print_hex(unsigned char *buf, int len, FILE *outFile)
{
  int i,n;
  char x='\n';
  for ( i = 0; i < len; i++ )
    {
      fprintf(outFile,"%02x",buf[i]); 
    } 
  fprintf(outFile,"%c",x);
  return (0); 
}

Since the key is a word. The words in the wordlist can be of size < or > 16 bytes and from my research on openssl it was said that there will be a pkcs#5 padding if the block length is does not fit into 16bytes. Is it the same case for the key also.

The cipher text I declared does not match with the cipher text I am generating from the program and I am unable to find the key for the cipher text.

I need help from the experts. I would appreciate if some one helps me in getting out of the trouble

Thanks in advance

A: 

What are you actually trying to achieve? Your code looks like an attempt to carry out a brute-force attack using a dictionary of passwords ... I'm not sure I should be trying to help with that!

I'll assume it's just an exercise ...

The first thing that strikes me is that you are setting your initialization vector (the variable iv) to a string of ASCII zeros. That's almost certainly wrong, and you probably need to use binary zeros.

unsigned char iv[16] = { 0 };

I don't know how the ciphertext that you have was generated (by another program, presumably) but I would imagine that that program didn't use the dictionary word itself as a key, but went through some sort of key derivation process first. You are using 128-bit AES as your encryption algorithm, so your keys should be 16 bytes long. You could achieve that by padding, as you suggest, but it's more usual to go through some process that mixes up the bits of the key to make it look more random and to distribute the key bits throughout the whole key. It wouldn't be unusual to hash the word and to use the output of the hash function rather than the word itself as key. Another possibility is that the dictionary word may be used as the input to a passphrase-based key derivation function such as that defined in PKCS#5.

You really need to find out how the word is used to generate a key before you can get any further with this.

dajames
A: 

Thank you very much for the reply.

Yes it is just an exercise and is like a dictionary attack. I am supposed to use iv with zeros but not ASCII zero, which is one of the mistakes I had made.

I assume the given cipher text is encrypted purely with a word from the word list without any hashing and might be padding is done but I am not sure because I am supposed to do find the key from the cipher text. The word list might have words less than 16 bytes or words greater than 16 bytes. So the problem I am thinking might be with the padding. I am thinking may be if the word length is less than 16 bytes, then I have to pad with either ASCII zeros or something like that. Which one do you suggest me to do and with little push may be I am finished.

Thanks

sandeep
Without knowing more of the background to your problem it's hard to say. If the words are less than 16 characters then padding (say with NULs) would be reasonable, but what should you do if the word is too long? Just truncate it? I doubt that any real-world crypto application would do anything so simple ...
dajames
A: 

Is there any one who can help me out in solving the program.

sandeep