15,905,874 members

See more:

I am trying to implement RSA using a C++ class.

Below is the class :

**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 :__

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).

Below is the class :

C#

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; } }

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).

Comments

See Encryption using the Win32 Crypto API[^], which should help.

Permalink

Share this answer

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!

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.

C++

/************************************************************************************ * 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; }

Permalink

Share this answer

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,
20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8
+1 (416) 849-8900

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