0

Below is my updated code. which works fine for encrypting but fails for decryption. i don't want padding and hence i am using no padding which also ensures that the output of encryption will be same for each run.

#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include <crypt.h>
#include <stdlib.h>
#include <openssl/rsa.h>
#include <openssl/aes.h>
#include <openssl/opensslconf.h>
#include <openssl/engine.h>
#include <openssl/pem.h>
#include <openssl/rc4.h>
#include <errno.h>

int main(void)
{
        //modulus in format char hex;
        char key[] = "dsfasdfsdfc58553eaa0e204e72b3e64d304c87192507926cb45062ee21d0ebef1bbf79d880d1f3e03f95b2264qwerewrwerw5b577226f9a9212b961209c6b85e9ed72adee43c387c8a9b7c1d74d018a03c498b09a84sadfsdfsdfsdfsadfasf2342f133d7";

        RSA * pubkey = RSA_new();

        BIGNUM * modul = NULL;
        BIGNUM * expon = NULL;

        //if(modul==NULL || expon==NULL || pubkey==NULL)
        //      printf("modul or expon or rsa could not be created\n");


        int len=BN_hex2bn(&modul, (const char *) key);

        printf("modul len = %d \n",len);
        printf("expon len =%d \n",BN_hex2bn(&expon, (const char *)"11"));

        printf("N KEY: [%s]\n",BN_bn2hex(modul));
        printf("E KEY: [%s]\n",BN_bn2hex(expon));

        pubkey->n = modul;
        pubkey->e = expon;
        pubkey->iqmp = NULL;
        pubkey->d = NULL;
        pubkey->p = NULL;
        pubkey->q = NULL;
        pubkey->dmp1=NULL;
        pubkey->dmq1=NULL;

        int size=RSA_size(pubkey);
        int size1;
        char text[size];
        char *encryptedText=(char*)malloc(size);
        char *decryptedText=(char*)malloc(size);
        int ret;
        char buf[100];

        memset(encryptedText,'\0',sizeof(encryptedText));

        strcpy(text,"4200000000000000|01|2012|121|V|122002-1111111111-NA");

        printf("size = [%d] strlen(text) = [%d] destText = [%s]\n",size,strlen(text),encryptedText);

//      srand(time(NULL));      //seeding random number generator

        if((size1=RSA_public_encrypt(size,(const unsigned char *)text,(unsigned char *)encryptedText,pubkey,RSA_NO_PADDING))<0)
        {
                printf("ERRO encrypt\n");
                printf("errno : [%d]\n",errno);
                ERR_error_string(errno, buf);
                printf("size1 =%d errno %d\n",size1,errno);
                printf("ERR STR [%s]\n",buf);
        }
        else
        {
                printf("SUCCESSFULLY encrypted\n");
                printf("bytes converted [%d]\n",size1);
                printf("ENC:: size [%d] string [%s]\n",strlen(encryptedText),encryptedText);
        }
 memset(decryptedText,'\0',sizeof(decryptedText));

        //      printf("size = [%d] encryptedText = [%s] decryptedText = [%s]\n",size,encryptedText,decryptedText);

                if((size=RSA_private_decrypt(size1,(unsigned char *)encryptedText,(unsigned char *)decryptedText,pubkey,RSA_NO_PADDING))<0)
                {
                printf("ERRO encrypt\n");
                printf("errno : [%d]\n",errno);
                ERR_error_string(errno, buf);
                printf("ERR STR [%s]\n",buf);
                }
                else
                {
                printf("SUCCESSFULLY decrypted\n");
                printf("bytes converted [%d]\n",size1);
                printf("DCRYPTED:: [%s]\n",decryptedText);
                }

        //      BN_free(expon);
        //      BN_free(modul);
        //      if(pubkey)

        free(encryptedText);
        free(decryptedText);
        RSA_free(pubkey);

        return 0;
}
2
  • What is the value of 'size', and what is the value of 'strlen(text)'? Commented Dec 27, 2013 at 11:14
  • You need to initialize private key parameters. See my answer below. Commented Dec 31, 2013 at 6:01

3 Answers 3

1

1> What is the value of 'size' which you have used in

char text[size];  
char encryptedText[size];`

2> It seems like you are trying to get value of size by
int size = RSA_size(pubkey); which appearently is rsa public key size.

You Cannot define array without specifying size of it. In your case you want to give size to your array at runtime.Thats not possible because Static arrays are allocated memory at compile time and the memory is allocated on the stack. So if you want to allocate memory at run time use dynamic array.

3> RSA_public_encrypt function takes first argument as length of data to be encrypted. so it will be better to use strlen(text) (as suggested by alk) instead of hardcoding it.

4> RSA_public_encrypt in your program is correctly encrypting the data. Problem is while printing.You are asking printf to print a string via the %s. so it prints the contents of the string till it encounters '\0' in encrypted buffer.

UPDATE
If RSA_NO_PADDING is used then input must have the same size as the modulus.
That means a 1024-bit RSA key works on 1024 bits of input and returns 1024 bits of output. If your input is not the same size as the key, you must use padding to make it so. If you do not use padding, than the RSA algorithm cannot be executed.
In terms of the OpenSSL API, the buffer that is passed in need to be 128 bytes.

Sign up to request clarification or add additional context in comments.

6 Comments

if((size1=RSA_public_encrypt(strlen(text),(const unsigned char *)text,(unsigned char *)encryptedText,pubkey,RSA_NO_PADDING))<0) ,this is my new version of code, now i have used strlen(text) to be encrypted and also i am dynamically allocating the to buffer i.e. encryptedText here, but still function is returning -1 but errno is 0, i wonder how is it possible ,and i can't change the method of generating my public key, if there is something wrong in the way please mention .. thanks guys
i have used padding , now function returns size of encrypted data which is different each time and output buffer contains value each time different. please bother..
Nitish bro, Actual confusion is in Padding what you are using. Consider if you are using RSA_PKCS1_OAEP_PADDING then your plaintext will be encoded to OAEP encoding form making it exact size of rsa modulus. SO your plain text will be encoded and then encrypted. and while decrypting it is decrypted first then decoded to your plaintext form.So nothing wrong with your program. Better try Decrypting it you will get exact data which you encrypted.
i have checked the link u mentioned above. and i understood the concept of padding but now my problem is the rsa_private_dercypt which causes segmentation fault and when i executed the program through gdb it mention : current function bounds could not found. i tried the same program on another machine but the problem persists there too.
|
1

The problem is, for RSA_private_decrypt(), you need the private key. But I don't see you have any private key with you. (i.e. rsa-> d (private exponent) must be known to you)

12 Comments

ok, but my problem persists with no padding to i am getting new a garbage value each time.
Well, you can't use strlen to get length of a binary data, and pritntf to print them. Better to get the length from the RSA_public_encrypt function and print the hex values inside a for loop. for(i = 0; i<size1; i++) printf("%02x ", encryptedText[i]);
@NitishKamal bgamlath is correct. when you use RSA_private_decrypt this function looks for privateExponent i.e d of your key. and in your program you are using public key for both encrypt and decrypt operation. this got nothing to do with padding. and its not garbage data.that data itself is encrypted data/cipher. It will be better if go through some basic tutorials.It seems you need some foundation for public key cryptography.
thanks Nimish Salve and bgamlath for clearifying me. actually i am converting a java code to corresponding c code. in java version , i get same output every time . and there the ouput i got is in a byte array and i convert that in hexadecimal, here in c version i use to do same and each time even after converting the output to hexadecimal i got different output.
And you are getting random values because of this. When you declare the char text[size], it has garbage values. When you use strcpy to fill it, only part of it get's filled.. rest is garbage. First clear the text array and then fill it. And also, in memset(encryptedText,'\0',sizeof(encryptedText));, sizeof(encryptedText) give you the size of the pointer variable, 4 or 8 depending on system you are in. It is because it is allocated dynamically. Use memset(encryptedText,'\0', size); instead.
|
0

1st issue I see is that in line

      if ((size1 = RSA_public_encrypt(
          size - 42,
          (const unsigned char *) text,
          (unsigned char *) encryptedText,
          pubkey,
          RSA_PKCS1_OAEP_PADDING)) < 0)

this

size - 42

should be

strlen(text)

From man RSA_public_encrypt (italics by me):

int RSA_public_encrypt(int flen, unsigned char *from, unsigned char *to, RSA *rsa, int padding);

[...]

DESCRIPTION

RSA_public_encrypt() encrypts the flen bytes at from (usually a session key) using the public key rsa and stores the ciphertext in to. to must point to RSA_size(rsa) bytes of memory.

1 Comment

@Nimish, my friend i have used padding now it is working but output is still garbage and each time different.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.