I am having problem encrytping and then decrypting messages using RSA 
withthe padding set to RSA_NO_PADDING. Most messages work, but some of 
them don't. By don't I mean the encryption/decryption process works fine 
except that the decrypted message is nothnig like the original! I have 
attached a C source file that demonstrates the problem.
My system is linux 2.4 and I have tried compiling the code with the 
redhat openssl-devel-0.9.6-3 rpm installed and with the lastest openssl 
tarball (dated 9-7-2001, openssl-0.9.6b.tar.gz).
Am I doing something wrong or is there a bug?

regards,
Patrick

-- 
Patrick Mackinlay                                [EMAIL PROTECTED]
ICQ: 59277981                                        tel: +44 7050699851
                                                      fax: +44 7050699852
SpaceSurfer Limited                          http://www.spacesurfer.com/
#include <openssl/ssl.h>

char *rsaMakeKeyString(char privateFlag, RSA *pKey)
 {
 BUF_MEM *pBuffer;
 char *pKeyString;
 BIO *pStringBIO = BIO_new(BIO_s_mem());

 if (pStringBIO==NULL)
  return NULL;
    
 if (privateFlag)
  PEM_write_bio_RSAPrivateKey(pStringBIO, pKey, NULL, NULL, 0, NULL, NULL);
 else
  PEM_write_bio_RSAPublicKey(pStringBIO, pKey);
    
 BIO_flush(pStringBIO);
 BIO_get_mem_ptr(pStringBIO, &pBuffer);
 /* --PIM-- Why set to noclose when it is no longer used when the function returns?
 BIO_set_close(pStringBIO, BIO_NOCLOSE); // So BIO_free() leaves BUF_MEM alone
  --/PIM-- */
 BIO_set_close(pStringBIO, BIO_CLOSE);
 pKeyString = malloc(pBuffer->length + 1);
 memcpy(pKeyString, pBuffer->data, pBuffer->length + 1);
 BIO_free(pStringBIO);

 return pKeyString;
 }

RSA* rsaLoadKey(char privateFlag, char *pKeyString)
 {
 RSA *pKey;
 BUF_MEM *pBuffer;
 BIO *pStringBio = BIO_new(BIO_s_mem());

 if (pStringBio==NULL)
  return NULL;
    
 pBuffer = BUF_MEM_new();
 BUF_MEM_grow(pBuffer, strlen(pKeyString) + 1);
 memcpy(pBuffer->data, pKeyString, strlen(pKeyString) + 1);
 BIO_set_mem_buf(pStringBio, pBuffer, BIO_CLOSE);

 if(privateFlag)
  pKey = PEM_read_bio_RSAPrivateKey(pStringBio, NULL, NULL, NULL);
 else
  pKey = PEM_read_bio_RSAPublicKey(pStringBio,NULL, NULL, NULL);

 BIO_free(pStringBio);
 if (pKey == NULL)
  return NULL;

 return pKey;
 }

char 
BuggyMessage[]="f687c3b86fe97c5cf69956c49bcbeef383849d757ad801cdfd5af57ef88c6a85416c7708a3cb727371b6b97d45bfc62abc42577865cf00e31de2402c8501f78fa36da4c4c46e6fd057a5ed978f008b897c858d6700cdb78c6a5da4bf87caf57f0ac2510e8d7f56607d9f5e3ed79d4df474426096680ae1f31548aae5fd032e03";

char 
WorkingMessage[]="6b334b5f8da27aff934f08f1df8e50b29828b896c99b3e85a7e6256d4a8c9f9dfea36a1af789c27d8a3cd50d8d0af8a1c269d525a116a347b251e7185130490edd01660a9a963dd6efb2a63af906616813c12800f86485761bbfda1c50fb7f22927b52143ef59f58368e9840cf014e5b5f03a667fea1b345353902e79ede07a2";

char *DecodeBytes(char *pInput, int length)
 {
 char *pOutput=malloc(length);
 int n;

 for(n=0; n<length; n++)
  {
  unsigned char *pV=&pOutput[n];
  *pV=(unsigned char)pInput[2*n] >= (unsigned char)'a' ? (unsigned 
char)pInput[2*n]-(unsigned char)'a'+10 : (unsigned char)pInput[2*n]-(unsigned char)'0';
  *pV=*pV<<4;
  *pV+=(unsigned char)pInput[2*n+1] >= (unsigned char)'a' ? (unsigned 
char)pInput[2*n+1]-(unsigned char)'a'+10 : (unsigned char)pInput[2*n+1]-(unsigned 
char)'0';
  }

 return pOutput;
 }


int main(int argc, char* argv[])
 {
 RSA *rsa, *rsa_pub, *rsa_priv;

 int orig_length, enc_length, dec_length;
 int i, j;
  
 unsigned char *original_message;
 unsigned char encrypted_message[255];
 unsigned char decrypted_message[255];
 char error[120];
 char *privateString;
 char *publicString;
    
 BIO *bio_out;

 // int pad = RSA_PKCS1_OAEP_PADDING;
 int pad = RSA_NO_PADDING;

 SSLeay_add_ssl_algorithms();
 SSL_load_error_strings();

 rsa = RSA_generate_key(1024, 65535, NULL, NULL);

 // printf("public modulus: %s\n", BN_bn2dec(rsa->n));
 // printf("public exponent: %s\n", BN_bn2dec(rsa->e));
 // printf("private exponent: %s\n", BN_bn2dec(rsa->d));
 // printf("p: %s\n", BN_bn2dec(rsa->p));
 // printf("q: %s\n", BN_bn2dec(rsa->q));

 printf ("RSA size: %d\n", RSA_size(rsa));

 publicString = rsaMakeKeyString(0, rsa);
 privateString = rsaMakeKeyString(1, rsa);

 printf("%s", publicString);
 printf("%s", privateString);

 rsa_pub = rsaLoadKey(0, publicString);
 rsa_priv = rsaLoadKey(1, privateString);
    /*  RSA_print_fp(stdout, rsa, 0); */
    
 // orig_length = strlen(original_message)+1;
 orig_length=128;
 original_message=DecodeBytes(BuggyMessage, orig_length);
    
 printf("Original message:\n");
 for (j = 0; j < orig_length;)
  {
  printf("%2.2x", original_message[j]);
  j++;
  if (j%32==0)
    printf("\n");
  }
 printf("\n");

 for (i= 0; i< 1; i++)
  {
  enc_length = RSA_public_encrypt(orig_length, original_message, encrypted_message, 
rsa_pub, pad);

  printf("Enclength: %d\n", enc_length);
        
  printf("Encrypted message:\n");
  for (j = 0; j < enc_length;)
   {
   printf("%2.2x", encrypted_message[j]);
   j++;
   if (j%32==0)
     printf("\n");
   }
  printf("\n");
  }
    
 ERR_print_errors_fp(stdout);
 dec_length = RSA_private_decrypt(enc_length, encrypted_message, decrypted_message, 
rsa_priv, pad);
 printf("Declength: %d\n", dec_length);
 printf("Decrypted message:\n");
 for (j = 0; j < dec_length;)
  {
  printf("%2.2x", decrypted_message[j]);
  j++;
  if (j%32==0)
    printf("\n");
  }
 printf("\n");

 if (strncmp(decrypted_message, original_message, orig_length)==0)
  printf("It worked\n");
 else
  printf("It failed\n");
 return 0;
 }

Reply via email to