Archived Forum Post

Index of archived forum posts

Question:

RSA Decryption, (problem with Encoding Mode)

Feb 20 '13 at 06:01

Hi,, I'm using the RSA Encryption and Decryption method in C++ Builder XE3, and its working properly. but the problem is that i wanted to divide the method into two functions, one for encryption and one for decryption. the encryption function is working properly, but the decryption function does not give me any results, i think the problem relies within the Encoding mode, where i don't know which one to use?

AND THIS IS THE DECRYPTION FUNCTION: the function passes the encrypted string, which i'm trying to decrypt.

String DecryptString(String enc) { CkRsa rsa; bool success; success = rsa.UnlockComponent("****");

success = rsa.GenerateKey(1024);
if (success != true) {
    ShowMessage(rsa.lastErrorText());
    return;
}

//  Now decrypt:
const char * privateKey;
privateKey = rsa.exportPrivateKey();
CkRsa rsaDecryptor;

//  Encrypt a string and return the encrypted data base64-encoded:
rsa.put_EncodingMode("utf-8");

rsaDecryptor.ImportPrivateKey(privateKey);

bool usePrivateKey = true;
const char * decryptedStr;
decryptedStr = rsaDecryptor.decryptStringENC((AnsiString(enc).c_str()),usePrivateKey);
ShowMessage(decryptedStr);

return decryptedStr;
}

So, can anyone please help me, and tell me which Encoding Mode to use!!!


Answer

Hi,,

i've finally figured out what was my problem. where i used to generate the public/private keys in a separate function called Generate_keys(), and when i wanted to perform encryption, i call this function to generate the public key, and then pass its result to the Encryption function. And then when i want to decrypt, i call it AGAIN to generate the private key,,, which resulted in generating an unmatched private key. Any way,i really appreciate your effort in helping me.

kind regards.


Answer

The EncodingMode to use depends on how your input data has been encoded. If your encrypted string is in Hex format, then use and EncodingMode of "hex". If it is in Base64, then use and EncodingMode of "base64".

If your encrypted string is not encoded (i.e. it is binary data), then you should be using the decryptString method on the encrypted byte array.


Answer

Hi,, I've tried your advice, but still cannot get any results. The ENCRYPT function is passed the string and the public key as follows: String Merchant::EncryptString(String mn, String gsmpk) { CkRsa rsa;

//  This example also generates the public and private
//  keys to be used in the RSA encryption.
//  Normally, you would generate a key pair once,
//  and distribute the public key to your partner.
//  Anything encrypted with the public key can be
//  decrypted with the private key.  The reverse is
//  also true: anything encrypted using the private
//  key can be decrypted using the public key

//  Start with a new RSA object to demonstrate that all we
//  need are the keys previously exported:
CkRsa rsaEncryptor;

//  We'll encrypt with the public key and decrypt with the private
//  key.  It's also possible to do the reverse.

rsaEncryptor.ImportPublicKey(AnsiString(gsmpk).c_str());

rsaEncryptor.put_EncodingMode("hex");

bool usePrivateKey;
usePrivateKey = false;
const char * encryptedStr;
encryptedStr = rsaEncryptor.encryptStringENC((AnsiString(mn).c_str()),usePrivateKey);
ShowMessage(encryptedStr);
return encryptedStr;

}

While the DECRYPT Function is passed the encrypted string and the private key as follows:

String Auth_Server::decrypt_recieved_mn_from_merchant(String enc_mn, String gsm_prik) { //Now decrypt: CkRsa rsa;

CkRsa rsaDecryptor;
rsaDecryptor.ImportPrivateKey(AnsiString(gsm_prik).c_str());
rsaDecryptor.put_EncodingMode("hex");

bool usePrivateKey;
usePrivateKey = true;
const char * decryptedStr;
decryptedStr = rsaDecryptor.decryptStringENC((AnsiString(enc_mn).c_str()),usePrivateKey);

ShowMessage(decryptedStr);
return  decryptedStr;

}

So, how can i solve this problem?,


Answer

I recommend:


Answer

Hi again..

I've tried checking the ImportPrivateKey return value, and it returned 1, and i've even printed out the private key just to make sure. And also did check on the decryptedStr, but nothing seems to work!!!!, it seems like the decryptStr has no value. And what did you mean by "post the LastErrorText in < pre> tags"?

The problem only appears when i divide the code into Encrypt and Decrypt functions, where the encrypt works but the decrypt doesn't!!!

What can i do?

String Merchant::EncryptString(String mn, String gsmpk) { CkRsa rsa;

bool success;
success = rsa.UnlockComponent("********");
if (success != true) {
  ShowMessage("RSA component unlock failed\n");
  return;
}

CkRsa rsaEncryptor;
rsaEncryptor.put_EncodingMode("hex");
rsaEncryptor.ImportPublicKey(AnsiString(gsmpk).c_str());

ShowMessage(gsmpk);

bool usePrivateKey;
usePrivateKey = false;
const char * encryptedStr;
encryptedStr = rsaEncryptor.encryptStringENC((AnsiString(mn).c_str()),usePrivateKey);
ShowMessage(encryptedStr);
return encryptedStr;

} String Auth_Server::decrypt_recieved_mn_from_merchant(String enc_mn, String gsm_prik) { //Now decrypt: CkRsa rsa;

bool success;
success = rsa.UnlockComponent("*****");
if (success != true) {
    ShowMessage("RSA component unlock failed\n");   }
CkRsa rsaDecryptor;
rsaDecryptor.put_EncodingMode("hex");
success=rsaDecryptor.ImportPrivateKey(AnsiString(gsm_prik).c_str());
if(success==false)
  ShowMessage(rsa.lastErrorText());

ShowMessage(gsm_prik);

bool usePrivateKey;
usePrivateKey = true;
const char * decryptedStr;
decryptedStr = rsaDecryptor.decryptStringENC((AnsiString(enc_mn).c_str()),usePrivateKey);

ShowMessage(decryptedStr);
return  decryptedStr;

}


Answer

I just tried writing similar code in VB6 using the latest CK DLL (9.4.0) and it's working for me now. Unfortunately, I don't use C++, and I can't really tell what could be wrong with your code, sorry!

If you post your LastErrorText return value after calling DecryptStringEnc, it might provide more information.


Answer

Some other thoughts:


Answer

Make sure that the public key used to encrypt is the counterpart of the private key used to decrypt. In other words, they must be private/public parts of the same key.

Do some basic debugging:

1) Examine in detail what is happening when encrypting:

- Examine the exact string contents passed to ImportPublicKey.  
- Make sure ImportPublicKey returns true for success.
- Examine the exact string to be encrypted that is passed to encryptStringENC.
- Examine the exact string returned by encryptStringENC.

2) Examine in detail what is happening when decrypting:

- Examine the exact string passed to ImportPrivateKey.  
- Verify that it matches the public key used for encrypting.  
- NOTE: A public key is actually just a sub-part of the private key.  
- You should see the public-key parts also present in the private key.  
- Verify the exact string passed to decryptStringENC.  Is it the same string as what was returned by encryptStringENC?

Finally, if the mistake was not found in doing the basic debugging, examine the LastErrorText contents after each Chilkat method call. Turn on VerboseLogging to get more information in LastErrorText.