Click here to Skip to main content
14,387,840 members
Rate this:
Please Sign up or sign in to vote.
See more:
I am trying to implement RSA using a C++ class.
Below is the class :


class rsacrypto
{
    long publickey;
    long privatekey;
    long modl; //Modulus





    public :

    rsacrypto(); //To be used to just generate private and public keys.
    rsacrypto(long &,long &,long &);//To be used just to generate private and public keys.
    rsacrypto(long key,long modulus) // Should be used when a data is to be encrypted or decrypted using a key.
    {
        publickey = privatekey = key;
        modl = modulus;
    }


    long ret_publickey()
    {
        return publickey;
    }
    long ret_privatekey()
    {
        return privatekey;
    }
    long ret_modulus()
    {
        return modl;
    }

    void encrypt(char *);
    void decrypt(char *);

};

rsacrypto::rsacrypto()
    {
        long p1,p2; //Prime numbers
        long n = 0; //Modulus
        long phi =0; //Totient value.

        long e = 0; //Public key exponent.
        long d = 0; //Private key exponent.

        p1 = genrndprimes(100,900);
        Sleep(1000);
        p1 = genrndprimes(100,900);

        n = p1*p2;
        phi = totient(n);

        e = genrndnum(2,(phi-1));

        while(gcd(e,phi)!=1)
        {
            e = genrndnum(2,(phi-1));
        }

        d = (1/e)%phi; //Modular Multiplicative Inverse.

        privatekey = e;
        publickey = d;
        modl = n;


    }


rsacrypto::rsacrypto(long &pubkey,long &privkey,long &mdls)
    {
        long p1,p2; //Prime numbers
        long n = 0; //Modulus
        long phi =0; //Totient value.

        long e = 0; //Public key exponent.
        long d = 0; //Private key exponent.

        p1 = genrndprimes(100,900);
        Sleep(1000);
        p1 = genrndprimes(100,900);

        n = p1*p2;
        phi = totient(n);

        e = genrndnum(2,(phi-1));

        while(gcd(e,phi)!=1)
        {
            e = genrndnum(2,(phi-1));
        }

        d = (1/e)%phi; //Modular Multiplicative Inverse.

        privatekey = e;
        publickey = d;

        pubkey = publickey;
        privkey = privatekey;
        mdls = n;
        modl = n;

    }


void rsacrypto::encrypt(char *dat)
{
    long siz = strlen(dat);
    for(long i=0;i<siz;i++)
    {
        dat[i]=(long)pow(dat[i],publickey)%modl;
    }
}

void rsacrypto::decrypt(char *datn)
{
    long sizz = strlen(datn);
    for(long i=0;i<sizz;i++)
    {
        datn[i]=(long)pow(datn[i],privatekey)%modl;
    }

}



genrndprimes(a,b) : Generates a random prime number between a and b (also inclusive of a and b if any or both a and b are prime).
genrndnum(a,b) : Generates a random number between a and b (also inclusive of a and b).


Main Program :


void main()
{
	char datm[]="Hello!! , Implementing RSA";
	
	rsacrypto m;
	long prkey = m.ret_privatekey();
	long publkey = m.ret_publickey();
	long modulm = m.ret_modulus();
	
	rsacrypto jj(publkey,modulm);
	rsacrypto ll(prkey,modulm);
	
	jj.encrypt(datm);
	
	puts(datm);
	
	cout<<"\n";
	
	ll.decrypt(datm);
	
	puts(datm);
	
	
}



The problem i face is this output :

Upon Encryption : 25 face characters (ASCII value value Unknown).
Upon Decryption : (SAME) 25 face characters (ASCII value Unknown).
Posted
Updated 3-Jun-13 23:29pm
v2
Comments
nv3 4-Jun-13 4:38am
   
Tried to use the debugger?
compuknow 4-Jun-13 4:40am
   
Can the Debugger sort out logical errors ?
nv3 4-Jun-13 5:49am
   
Of course; run your program in the debugger and find the place where the program does something different from you you, the designer, are expecting. As long as you don't know how to use your debugger you are more or less helpless as a software developer.
compuknow 4-Jun-13 6:50am
   
Can you suggest a good Debugger?
nv3 4-Jun-13 7:10am
   
Depends on your development environment. Visual Studio contains its own debugger, which is excellent. Most other IDEs also contain a debugger which is tuned to their environment.
zlogdan 4-Jun-13 9:56am
   
Don't use the same buffer for your conversion and input, better allocate memory for the result and returning it from a class method like char* getResult() const; Also, I would check the buffers using and hex editor like HxD. Please post the strings you are getting here, I am just guessing you need to convert your output data from binary to ASCII so the puts C function works fine.
compuknow 4-Jun-13 10:58am
   
The output is 25 'smiling face' characters. This codeproject's HTTP interface does not allow those characters. Neither do I know the ASCII value of the output cipher characters. This is the problem I face in showing you the output.
nv3 4-Jun-13 11:46am
   
Why don't you output the result of the encryption and decryption in hex? That will show you what happens.
saeedbahal 2-Feb-15 4:08am
   
i am try to run this program in dev c++ but i face problem in below code:
dat[i]=(long)pow(dat[i],publickey)%modl;
and this error appear in compile:
call of overloaded `pow(char&, long int&)' is ambiguous
please help me to solve this error
Rate this:
Please Sign up or sign in to vote.

Solution 1

See Encryption using the Win32 Crypto API[^], which should help.
   
Comments
compuknow 4-Jun-13 6:54am
   
Actually I wished to create it on My Own. How will I know whether or not Win32 API has an intended backdoor.
Richard MacCutchan 4-Jun-13 6:57am
   
What do you mean by "intended backdoor"? I appreciate you may want to do this yourself, but if that is the case, then you need to be sure you implement every part of the RSA algorithm.
zlogdan 4-Jun-13 9:57am
   
Richard nailed it man! Also thanks for the link!
Rate this:
Please Sign up or sign in to vote.

Solution 2

Hi, I don't mean to post a solution to this but I could not post code on the comments. Ihad written these two functions sometime ago for debugging. Not sure if they fit your needs. Also they can be improved and optimized. Hope they help you, the comments sort of explain what they do. With them you can convert a binary array of bytes to its ascii representation.


/************************************************************************************
* int CMFRegisterLogger::iConvertBinArray2String( char* bBindata, 
*						  int iDataSize,
*						  char* szDataString )
* description: Originally the data from the MF is binary, thus to print it in a file we must convert
* it to an ASCII representation of this array of bytes. This convertion is not literal,
*			   because each nibble of the bin values is converted to an ASCII byte. The output is
*			   twice as big as the input
* INPUT:		Original data buffer and its size
* OUTPUT:	 	New buffer	
* RETURNS:	    returns 0 OK else 1
*************************************************************************************/
int iConvertBinArray2String(				char* bBindata, 
											int iDataSize,
											char* szDataString )

{	

	if (( bBindata == NULL )||(szDataString) == NULL )
		return 1;

	for(int i = 0; i < iDataSize ; i++)
	{
		char tmp[3];
		memset(tmp,0,3);
		sConvertHexBin2String((unsigned char)bBindata[i],(unsigned char*)tmp);
		memcpy((szDataString+2*i),tmp,2);
	}

	return 0;
}
/************************************************************************************
*unsigned char* CMFRegisterLogger::sConvertHexBin2String(unsigned char ch, unsigned char* buffer)
* description: Originally the data from the MF is binary, thus to print it in a file we must convert
*			   it to an ASCII representation of this array of bytes. This convertion is not literal,
*			   because each nibble of the bin values is converted to an ASCII byte. The output is
*			   twice as big as the input. This method actually converts each nibble of a byte to
*			   its ascii representation.
* INPUT:		A char
* OUTPUT:	 	2 byte ASCII array representation
* RETURNS:	    Pointer of the first byte of this array ( includes NULL terminator )
*************************************************************************************/
unsigned char* sConvertHexBin2String(unsigned char ch, unsigned char* buffer)
{
  char tmp[3];
  memset(tmp,0,3);
  if ( (ch&0x0F) == 0 )
  {
		if ( ch == 0x00 )
		{
				tmp[0] = 0x30;
				tmp[1] = 0x30;
				tmp[2] = 0x00;
		}
		else
		{
				sprintf(tmp,"%x",ch);
				if ( tmp[1] == 0 )
					tmp[1] = 0x30;
		}
  }
  else
  if ( ((ch&0xF0)<<4) == 0 )
  {
	    char cfix = 0x00;
		sprintf(tmp,"%x",ch);
		cfix = tmp[0];
		tmp[0] = 0x30;
		tmp[1] = cfix;
  }
  else
		sprintf(tmp,"%x",ch);
  memcpy(buffer,tmp,3);	
  return buffer;  
}
   
v6
Comments
compuknow 4-Jun-13 21:18pm
   
Actually , what do you mean by a binary array of bytes? Do they mean each element in the array are in boolean 0's and 1's format? The problem is I dont understand in which situations I must use these functions.
zlogdan 5-Jun-13 8:24am
   
No, for example, your code might be generating values like 0x04, 0x05. And if you try to output these chars they won't have any readable ascii representation. So, you need to convert it to a C string like "0405" or convert every item of the array separately and display them. If you try a cout << with a binary buffer say { 0x04, 0x05 } you will get those weird chars.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)




CodeProject, 503-250 Ferrand Drive Toronto Ontario, M3C 3G8 Canada +1 416-849-8900 x 100