Hi all,
I have been trying with RSA encryption and decryption. I was able to write a code which worked fine. Then I split it into functions as part of a requirement. However I am not getting the expected result everytime. I know it has something to do with how I am returning but it just does not seem to work out. The original program is here:
http://www.unix.com/high-level-programming/90293-pem\_read_rsapublickey-returns-null.html
The modified code is here:
#include <stdio.h>
#include <algorithm>
#include <iostream.h>
#include <stdlib.h>
#include <string.h>
#include <fstream.h>
#include <sys/stat.h>
#include "openssl/crypto.h"
#include "openssl/x509.h"
#include "openssl/pem.h"
#include "openssl/ssl.h"
#include "openssl/err.h"
#include "openssl/rsa.h"
int passphrase_cb(char *buf, int len,int flag, void *u)
{
char *passphrase="mypassword";
cout<<"Inside callback"<<endl;
int passphrase_len;
passphrase_len = strlen(passphrase);
/* Check sufficient space exists for the passphrase including
* the NULL terminator in the buffer, otherwise truncate.
*/
if (passphrase_len > (len-1))
passphrase_len = (len-1);
memcpy(buf, passphrase, passphrase_len);
/* return the actual passphrase length */
return (passphrase_len);
}
void generateRSAKeys(){
cout<<"Generating RSA keys"<<endl;
RSA *rsa=NULL;
FILE *fp;
OpenSSL_add_all_algorithms();
if ((rsa=RSA_generate_key(2048,65537,NULL,NULL)) == NULL){
cout<<"Creation of keys failed"<<endl;
}else{
cout << "success"<<endl;
}
fp = fopen("server_public.key","w");
if (!PEM_write_RSAPublicKey(fp, rsa )){
cout<<"Error writing public key"<<endl;
}
else{
cout<<"Public key written succesfully"<<endl;
}
fclose(fp);
fp = fopen("server_private.key","w");
if (!PEM_write_RSAPrivateKey(fp, rsa, EVP_des_ede3_cbc(), (unsigned char *)"mypassword" , strlen("mypassword"),NULL, NULL)){
cout<<"Error writing private key"<<endl;
}
else{
cout<<"Private key written succesfully"<<endl;
}
fclose(fp);
RSA_free(rsa);
}
/***************************************************************/
std::string newEncryptString(const char *input) {
FILE *pubFile, *privFile;
struct stat info;
int pubRet=stat("/home/mtc/test/server_public.key",&info);
int privRet=stat("/home/mtc/test/server_private.key",&info);
cout<<"pubRet="<<pubRet<<endl;
cout<<"privRet="<<privRet<<endl;
if ((pubRet!=0) || (privRet!=0)) {
cout<<"Public and Private key files not present"<<endl;
generateRSAKeys();
}
pubFile=fopen("server_public.key","r");
RSA *rsa=RSA_new();
RSA_blinding_off(rsa);
rsa = PEM_read_RSAPublicKey(pubFile, NULL, NULL, NULL);
if (rsa==NULL){
cout<<"Reading of Public key not successfull"<<endl;
}
char *encryptedString=(char *)malloc(RSA_size(rsa));
if (RSA_public_encrypt(strlen(input)+1,(unsigned char*)input,(unsigned char*)encryptedString,rsa,RSA_PKCS1_PADDING)==-1){
cout<<"encryption failed "<<endl;
}
RSA_free(rsa);
fclose(pubFile);
std::string cipherText=encryptedString;
cout<<"Returning from encrypt"<<endl;
return cipherText;
}
/*****************************************************************/
std::string newDecryptString(std::string& input) {
cout<<"Length here "<<sizeof(input)<<endl;
OpenSSL_add_all_algorithms();
cout<<"Reached after adding alogo"<<endl;
FILE *privFile;
privFile = fopen("/home/mtc/test/server_private.key","r");
RSA *rsa=RSA_new();
RSA_blinding_off(rsa);
int (*cb)(char *buf, int buflen, int flag, void *u);
cb=passphrase_cb;
cout<<"Cb value inside decrypt:"<<cb<<endl;
rsa = PEM_read_RSAPrivateKey(privFile, NULL, cb, NULL);
if (rsa==NULL){
cout<<"Reading of private key not successful"<<endl;
}
if (RSA_check_key(rsa) != 1){
cout<<"RSA_check_key(): PrivateKey check failed\n";
}
char *plainText=(char *)malloc(RSA_size(rsa));
if (RSA_private_decrypt(RSA_size(rsa),(unsigned char *)input.c_str(),(unsigned char*)plainText,rsa,RSA_PKCS1_PADDING)==-1){
cout<<"Decryption failed "<<endl;
}
fclose(privFile);
int len=RSA_size(rsa);
RSA_free(rsa);
std::string decryptedString(plainText);
free(plainText);
return decryptedString;
}
/*********************************************************************/
int main(int argc, char *argv[])
{
std::string cipherOut(newEncryptString("trialstring"));
cout<<"Plain string="<<newDecryptString(cipherOut)<<endl;
return 0;
}
I am getting expected result only at times. Many times I get the error "Decryption failed". However no other error is happening. Could someone please suggest how to make this working fine?
Thanks