Hi,

I've been writing a program that encrypts and stores passwords (it's for uni, I'm a newbie), and I'm having a problem with some misbehaving variables. I hope someone can shed some light on it for me. :)

I have a function which takes a string as a parameter and returns an encrypted version of the string. I'm using the alleged RC4 algorithm so this function also works to decrypt a string the same way. The algorithm encrypts by XORing the plaintext against a pseudo-random pad (which in my implementation is the output of the step() function of the rc4 object). The pad is initialised with a key (which can be a string of any length, but I've made it 8 for now).

I've stripped out all the code for the actual encryption to simplify things and written a main() to call the function a couple of times.

The problem is this:
I declare two variables at the begining of the crypt() function, a string with value "changeme", and an int with value 8 (the number of letters in "changeme".
I then immediately output the value of the int and the length of the string to cout (for diagnostic purposes).
The first time the function is called there is no problem.
The second time I call the function the output says the string variable is length 10 and the length variable is 10 also.
If I comment out the call to rc4.step() the problem goes away.

I'm confused because the rc4 object is within the local scope of the crypt() function, and it's also called after I output the values, so I don't see how it could affect the variables the second time through, but it seems to.

Another interesting thing.. I've found that if I make the key less than 8 characters I don't have the problem.

Here are my files:

rc4.h

typedef unsigned char UnsignedChar;     // named uns8 in the textbook
typedef unsigned char* UnsignedCharPtr;
typedef unsigned short UnsignedShort;   // named uns16 in the textbook

// rc4 algorithm from Kaufman et al "Network Security", 2002 (page 93).
// Translated from C to C++


class rc4 {

public:
  void init (UnsignedCharPtr key, UnsignedShort length);
  UnsignedChar step();
 
private:
  UnsignedChar state[256], x, y;  // 258 octets of state information

};

rc4.cpp

#include "rc4.h"
#include <iostream>

// rc4 algorithm from Kaufman et al "Network Security", 2002 (page 93).
// Translated from C to C++

void rc4::init (UnsignedCharPtr key, UnsignedShort length) {
  // initialize for encryption/decryption
  int i;
  UnsignedChar t, j;
  UnsignedChar k = 9;

  // print out key
  std::cout << "\nRC4 reports key as: \"";
  for(int counter = 0; counter < length; counter++)
   {
    std::cout << key[counter];
   }
  std::cout << "\"";


  for (i = 256; i--; )
    state[i] = i;

  for (i=0, j=0; i<256; i++, j = (j+1) % length)
    t = state[i], state[i] = state[k+= key[j] + t], state[k] = t;

  x = 0;
  y = 0;
}

UnsignedChar rc4::step() { // return next pseudo-random octet
  UnsignedChar t;
  t = state[y += state[++x]], state[y] = state[x], state[x] = t;
  std::cout << "\nstep returning: " << std::oct << (unsigned int)state[state[x] + state[y]];

  return (state[state[x] + state[y]]);
}

keytest.cpp

// requires the files rc4.cpp and rc4.h
// To compile: g++ keytest.cpp rc4.cpp

#include <iostream>
#include <string>
#include <map>
#include "rc4.h"
using namespace std;

string crypt(string msg_str)
 {
  // set key string and hardcode the length of the string
  string rc4keystring = "changeme";  // rc4keystring is set to a string of length 8.
  int rc4key_length = 8;             // rc4key_length is set to 8.

  // The second time this function is called, why do
  // the next two lines output the key length as 10?
  cout << "\nkey length: " << rc4keystring.length();
  cout << "\nlength variable: " << rc4key_length;

  // convert key string to array of unsigned char
  // so that it can be passed to the rc4 initialiser.
  unsigned char key[rc4key_length];
  for(int x=0; x < rc4key_length; x++)
   {
    key[x] = (unsigned char)rc4keystring[x];
   }

  // declare and initialise rc4 object
  rc4 rc4obj;
  rc4obj.init(key, (unsigned short)rc4key_length);

  // The key length output is as expected
  // if you comment out the next line.
  rc4obj.step();

  return "test output";
 }

int main()
 {
  map<string, string> realmPasswords;
  string realm = "realmName";
  string pass = "realmPassword";

  cout << "\n\nAssign realm/password pair";
  realmPasswords[realm] = crypt(pass);  // inserts key/value pair into map

  cout << "\n\nRetrieve password";
  pass = crypt(realmPasswords[realm]);

  cout << "\n\npassword: " << pass << "\n\n";
}

As an update (hopefully not a shameless bump, there doesn't seem to be an option to edit my OP):

I've found that commenting out line 35 of rc4.cpp causes the strange behaviour to stop. But I'm still confused because that line simply prints a diagnostic.

There is no assignment, so no varibales should change. And besides that, the variables that appear to change are out of scope...

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.