Openssl evp api(aes256cbc) का उपयोग करके फ़ाइल को एन्क्रिप्ट करने वाले मुद्दे




linux encryption (2)

मुझे लगता है कि आपका विश्लेषण गलत है यह लूप समस्याग्रस्त है:

while((rd = read(in,buf,SIZE)) >0)
{
    dbug_p("\nREAD::%s::\n",buf);
    encry = aes_encrypt(&en,(unsigned char*) buf, &rd);
    dbug_p("\n EN::%s::\n",encry);
    decry = aes_decrypt(&de,(unsigned char*) encry,&rd);
    dbug_p("\n DE::%s::\n",decry);

            free(encry);
        free(decry);
}

सबसे पहले क्योंकि आप %s का उपयोग करके प्रिंट करते हैं, जो शून्य टर्मिनेटर की अपेक्षा करता है। हालांकि, एन्क्रिप्टेड / डिक्रिप्टेड डेटा शून्य समाप्त नहीं है। इसके बजाय, आपको for (i = 0; i < rd; i++) printf("%02x "); लूप का उपयोग करके rd वर्णों को प्रिंट करना चाहिए for (i = 0; i < rd; i++) printf("%02x "); - यही कारण है कि आपके समस्या का विश्लेषण संभवतः दोषपूर्ण है।

दूसरे, मुझे लगता है कि आपकी वास्तविक समस्या में, आप एक समय में SIZE बाइट पढ़ रहे हैं और उन्हें aes_decrypt() अलग से भेज रहे हैं। यह विफल हो जाएगा क्योंकि EVP_DecryptFinal_ex() को बहुत जल्दी बुलाया जा रहा है (सभी एन्क्रिप्टेड ब्लॉक पढ़े जाने से पहले)। आपके पास दो विकल्प हैं या तो आप प्रत्येक पाश चलने में EVP_DecryptUpdate() माध्यम से पढ़ने वाले बाइट्स भेजते हैं, और लूप (और लूप से पहले इनट तदनुसार EVP_DecryptFinal() को पूरा करने के बाद EVP_DecryptFinal() को कॉल करें, या आप पूरी फ़ाइल को बफर में पहले पढ़ते हैं, और फिर इसे aes_decrypt() माध्यम से aes_decrypt() एक बार में

या दूसरे शब्दों में, आपको aes_encrypt() बाद में aes_encrypt() बाद के परिणामस्वरूप पूरे डेटा ब्लॉक को भेजने की आवश्यकता है। आप उन्हें अलग-अलग हिस्सों में नहीं भेज सकते हैं, जब तक आप फ़ंक्शन को विभाजित नहीं करते और अलग-अलग हिस्सों पर EVP "update" फ़ंक्शन का उपयोग नहीं करते हैं।

मैं इस मामले में फ़ाइल (.टीटीटी) पढ़ने की कोशिश कर रहा हूं और इसे एईएस 256 सीबीसी के साथ एन्क्रिप्ट करते हुए एन्क्रिप्ट / डिक्रिप्ट कर ईएसपीपी के एपनएसएल का उपयोग कर रहा हूं। (- (encrypt.txt बनाने>) - plain.txt पढ़ें ()> बनाने (decrypt.txt))

# include <stdio.h>
# include <stdlib.h>
# include <openssl/evp.h>
# include <openssl/aes.h>
# include <sys/types.h>
# include <sys/stat.h>
# include <fcntl.h>
# include <unistd.h>
# include <string.h>
# include <assert.h>
# include <error.h>
# include "debug.h"
# define SIZE 32

char buf[SIZE];

int aes_init(unsigned char* pwd, unsigned int pwd_len, unsigned char * salt, EVP_CIPHER_CTX *e_ctx, EVP_CIPHER_CTX *d_ctx)
{
    int i, rounds =5;                   /* rounds */
    unsigned char key[32], iv[32];

    i = EVP_BytesToKey(EVP_aes_256_cbc(),EVP_sha1(),salt,pwd,pwd_len,rounds,key,iv);
    if(i != 32)
    {
      printf("\n Error,Incorrect key size generated:%d:\n",i);
      return -1;
    }

    EVP_CIPHER_CTX_init(e_ctx);
    EVP_EncryptInit_ex(e_ctx, EVP_aes_256_cbc(), NULL, key, iv);
    EVP_CIPHER_CTX_init(d_ctx);
    EVP_DecryptInit_ex(d_ctx, EVP_aes_256_cbc(), NULL, key, iv);

    return 0;
}

unsigned char* aes_encrypt(EVP_CIPHER_CTX *e,unsigned char * plain_text, unsigned int * len )    /* this function encryptes the  file:fd is passed as parameter */
{
    int ci_len = (*len) + AES_BLOCK_SIZE;
    int flen =0;
    unsigned char * cipher_text = malloc(ci_len);

    EVP_EncryptInit_ex(e, NULL, NULL, NULL, NULL);              /* allows reusing of e for multiple cipher cycles */
    EVP_EncryptUpdate(e, cipher_text, &ci_len, plain_text, *len);       /* Update cipher text */
    EVP_EncryptFinal_ex(e, cipher_text+ci_len, &flen);          /* updates the remaining bytes */
    *len = ci_len + flen;

    return cipher_text; 
}

unsigned char* aes_decrypt(EVP_CIPHER_CTX *e, unsigned char * c_text, unsigned int * len)
{
    int pi_len = (*len);
    int flen = 0;
    unsigned char * plain_text = malloc(pi_len);

    EVP_DecryptInit_ex(e, NULL, NULL, NULL, NULL);
    EVP_DecryptUpdate(e, plain_text, &pi_len, c_text, *len);
    EVP_DecryptFinal_ex(e, plain_text+pi_len, &flen);

    (*len) = pi_len + flen;
    return plain_text;
}

int main(int argc,char **argv)
{
    if(argc != 2)
    {
      perror("\n Error:\nCorrect Usage: Enter Password to be used");
      exit(-1);
    }

    EVP_CIPHER_CTX en,de;                   /* The EVP structure which keeps track of all crypt operations see evp.h for details */
    int in, out, fd, dec,i =0;                  /* fd for input and output files and random dev*/
    unsigned int pwd_len = strlen((const char *)argv[1]);           /* Length of the pwd supplied by the user */
    unsigned char *pwd =(unsigned char*) argv[1];           /* Pointer to the pwd supplied by the user */
    unsigned int rd= 0;
    unsigned char salt[8];
    unsigned char * encry = NULL, *decry = NULL;
    i =0;
    if((in = open("plain.txt",O_RDONLY)) == -1)          /* Opening a plain text file for encryption */
    {
      perror("\n Error,Opening file for reading::");
      exit(-1);
    }

    if((fd = open("/dev/random", O_RDONLY)) == -1)
    {
      perror("\n Error,Opening /dev/random::");
      exit(-1);
    }
    else
    {
      if(read(fd,salt,8) == -1)
      {
        perror("\n Error,reading from /dev/random::");
        exit(-1);
      }
    }

    if(aes_init(pwd,pwd_len,(unsigned char*) salt,&en,&de))     /* Generating Key and IV and initializing the EVP struct */
    {
      perror("\n Error, Cant initialize key and IV:");
      return -1;
    }

    if((out = open("encrypt.txt",O_RDWR|O_CREAT,0400 | 0200)) == -1)
    {
      dbug_p("ENC%d",out);
      perror("\n Error,Opening the file to be written::");
      exit(-1);
    }

    rd =0;
    while((rd = read(in,buf,SIZE)) >0)
    {
      dbug_p("\nREAD::%s::%d*\n",buf,rd);
      encry =   aes_encrypt(&en,(unsigned char*) buf, &rd);
      if((write(out,encry,rd)) != rd)
      {
        perror("\n Error,Required encrypted bytes not written::");
        exit(-1);
      }     
      free(encry);
    }

    rd =0;
    if((dec = open("dec22.txt",O_RDWR|O_CREAT,0400 | 0200)) == -1)
    {   
      dbug_p("dec%d",dec);
      perror("\n Error,Opening the decrypting o/p file::");
      exit(-1);
    }

    if((lseek(out,0,SEEK_SET)) != 0) perror("\n Error:setting lseek::");
    for(i=0;i<SIZE;i++) buf[i] =0;
    while((rd = read(out,dbuf,SIZE)) >0)
    {
      decry = aes_decrypt(&de,(unsigned char*) dbuf, &rd);
      if((write(dec,decry,rd)) != rd)
      {
        perror("\n Error,Required decrypted bytes not written::");
        exit(-1);
      }
      free(decry);
    }

    close(in);
    close(fd);
    EVP_CIPHER_CTX_cleanup(&en);
    EVP_CIPHER_CTX_cleanup(&de);
    return 0;
}

मेरी समस्या यह थी कि जब मैं एक एन्क्रिप्टेड फ़ाइल को डिक्रिप्ट करता हूं, मुझे एक ऐसी फाइल मिलती है जो ठीक से डिक्रिप्टेड नहीं है (उदाहरण के लिए सही स्ट्रिंग कचरा सही स्ट्रिंग कूड़ा ...)

[email protected]:~/mpro/EFF$ cat plain.txt 
Today is tuesday
tomorrow is wednesday
then thursday and friday and saturday
finally sunday

डिक्रिप्टेड फ़ाइल

cat dec22.txt 
Today is tuesdayw)Q������O-%�A8���R��.�O���and saturday
finally sunday

इसका कारण क्या हो सकता है? क्या यह कुछ और भी पढ़ रहा है या मैं कहीं कोई मूर्ख त्रुटि बना रहा हूँ

संपादित करें : अगर मैं सिर्फ किसी एरेक्ट को एन्क्रिप्ट करता है (36 बरतने की कोशिश की है) तो यह किसी भी कचरा को प्रिंट किए बिना सही ढंग से एन्क्रिप्ट और डिक्रिप्ट किया गया है।

मुझे लगता है कि मैं (* हैंडलिंग नहीं) कुछ * निक फ़ाइल संरचना विवरण याद कर रहा हूँ .. ?? या फ़ाइल पर इस एनक्रिप्शन को करने का कोई बेहतर तरीका है।

बहुत धन्यवाद


while((rd = read(in,buf,SIZE)) >0)
{
    dbug_p("\nREAD::%s::%d*\n",buf,rd);
    encry = aes_encrypt(&en,(unsigned char*) buf, &rd);

तथा,

unsigned char* aes_encrypt(EVP_CIPHER_CTX *e,unsigned char * plain_text, unsigned int * len )    /* this function encryptes the  file:fd is passed as parameter */
  {
int ci_len = (*len) + AES_BLOCK_SIZE;
int flen =0;
unsigned char * cipher_text = malloc(ci_len);

EVP_EncryptInit_ex(e, NULL, NULL, NULL, NULL);              /* allows reusing of e for multiple cipher cycles */
EVP_EncryptUpdate(e, cipher_text, &ci_len, plain_text, *len);       /* Update cipher text */
EVP_EncryptFinal_ex(e, cipher_text+ci_len, &flen);          /* updates the remaining bytes */

आप EVP_EncryptFinal_ex कई बार कॉल कर रहे हैं इसे अंत में केवल एक बार कहा जाना चाहिए। वही सही है कि आप डिक्रिप्शन कैसे कर रहे हैं

यहां एन्क्रिप्ट करने के लिए मैन पेज से एक सरल उदाहरण है डिक्रिप्शन के लिए एक समान फ़ंक्शन है और इसे कार्य करना चाहिए

int do_crypt(char *outfile)
       {
       unsigned char outbuf[1024];
       int outlen, tmplen;
       /* Bogus key and IV: we'd normally set these from
        * another source.
        */
       unsigned char key[] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
       unsigned char iv[] = {1,2,3,4,5,6,7,8};
       char intext[] = "Some Crypto Text";
       EVP_CIPHER_CTX ctx;
       FILE *out;
       EVP_CIPHER_CTX_init(&ctx);
       EVP_EncryptInit_ex(&ctx, EVP_bf_cbc(), NULL, key, iv);

       if(!EVP_EncryptUpdate(&ctx, outbuf, &outlen, intext, strlen(intext)))
               {
               /* Error */
               return 0;
               }
       /* Buffer passed to EVP_EncryptFinal() must be after data just
        * encrypted to avoid overwriting it.
        */
       if(!EVP_EncryptFinal_ex(&ctx, outbuf + outlen, &tmplen))
               {
               /* Error */
               return 0;
               }
       outlen += tmplen;
       EVP_CIPHER_CTX_cleanup(&ctx);
       /* Need binary mode for fopen because encrypted data is
        * binary data. Also cannot use strlen() on it because
        * it wont be null terminated and may contain embedded
        * nulls.
        */
       out = fopen(outfile, "wb");
       fwrite(outbuf, 1, outlen, out);
       fclose(out);
       return 1;
       }

निम्न उदाहरण एक फ़ाइल को आपके केस के रूप में पढ़ रहा है। देखें कि Update (कई बार कहा जाता है) और Final (एक बार अंत में) दिनचर्या का उपयोग किया जाता है।

int do_crypt(FILE *in, FILE *out, int do_encrypt)
        {
        /* Allow enough space in output buffer for additional block */
        inbuf[1024], outbuf[1024 + EVP_MAX_BLOCK_LENGTH];
        int inlen, outlen;
        /* Bogus key and IV: we'd normally set these from
         * another source.
         */
        unsigned char key[] = "0123456789";
        unsigned char iv[] = "12345678";
        /* Don't set key or IV because we will modify the parameters */
        EVP_CIPHER_CTX_init(&ctx);
        EVP_CipherInit_ex(&ctx, EVP_rc2(), NULL, NULL, NULL, do_encrypt);
        EVP_CIPHER_CTX_set_key_length(&ctx, 10);
        /* We finished modifying parameters so now we can set key and IV */
        EVP_CipherInit_ex(&ctx, NULL, NULL, key, iv, do_encrypt);
        for(;;)
                {
                inlen = fread(inbuf, 1, 1024, in);
                if(inlen <= 0) break;
                if(!EVP_CipherUpdate(&ctx, outbuf, &outlen, inbuf, inlen))
                        {
                        /* Error */
                        EVP_CIPHER_CTX_cleanup(&ctx);
                        return 0;
                        }
                fwrite(outbuf, 1, outlen, out);
                }
        if(!EVP_CipherFinal_ex(&ctx, outbuf, &outlen))
                {
                /* Error */
                EVP_CIPHER_CTX_cleanup(&ctx);
                return 0;
                }
        fwrite(outbuf, 1, outlen, out);
        EVP_CIPHER_CTX_cleanup(&ctx);
        return 1;
        }




aes