2015-12-16 4 views
8

मेरे पास निम्न क्वेरी है। क्या कोई भी मुझे समाधान का सुझाव दे सकता है।फ़ाइल डिक्रिप्शन के दौरान "EVP_DecryptFInal_ex: खराब डिक्रिप्ट" को हल करने के लिए कैसे करें

मैं पहली बार फ़ाइल के एन्क्रिप्शन और डिक्रिप्शन पर काम कर रहा हूं।

मैं आदेश का उपयोग कमांड प्रॉम्प्ट के माध्यम से फ़ाइल एन्क्रिप्ट है

openssl enc -aes-256-cbc -in file.txt -out file.enc -k "key value" -iv "iv value" 

मैं इसे प्रोग्राम के रूप में डिक्रिप्ट करने के लिए किया है। तो मैं इसके लिए कार्यक्रम में लिखा है, लेकिन यह निम्न त्रुटि फेंक है:

./exe_file enc_file_directory 
... 
error: 06065064: digital envelope routines: EVP_DecryptFInal_ex: bad decrypt: evp_enc.c 

कार्यक्रम नीचे निर्देशिका पथ के रूप में इनपुट लेता है और एन्क्रिप्टेड फ़ाइल ".enc" के लिए खोज और इसे पढ़ने के डिक्रिप्ट करने के लिए कोशिश बफर में

कोड:

#include <stdio.h> 
#include <string.h> 
#include <stdlib.h> 
#include <dirent.h> 
#include <sys/stat.h> 
#include <sys/types.h> 
#include <openssl/evp.h> 
#include <openssl/err.h> 
#include <openssl/conf.h> 
#include <libxml/globals.h> 

void handleErrors(char *msg) 
{ 
    { 
     ERR_print_errors_fp(stderr); 
     printf("%s", msg); 
     abort(); 
    } 
} 

void freeMemory(char *mem) 
{ 
    if (NULL != mem) 
    { 
     free(mem); 
     mem = NULL; 
    } 
} 

/* Function to decrypt the XML files */ 

int decryptXML(unsigned char *indata, unsigned char *outdata, int fsize) 
{ 

    int outlen1 = 0, outlen2 = 0; 

    unsigned char iv[] = "b63e541bc9ece19a1339df4f8720dcc3"; 
    unsigned char ckey[] = "70bbc518c57acca2c2001694648c40ddaf19e3b4fe1376ad656de8887a0a5ec2" ; 

    if (NULL == indata) 
    { 
     printf ("input data is empty\n"); 
     return 0; 
    } 

    if (0 >= fsize) 
    { 
     printf ("file size is zero\n"); 
     return 0; 
    } 

    outdata = (char *) malloc (sizeof (char) * fsize * 2); 

    EVP_CIPHER_CTX ctx; 

    EVP_CIPHER_CTX_init(&ctx); 

    if (! EVP_DecryptInit_ex (&ctx, EVP_aes_256_cbc(), NULL, ckey, iv)) 
    { 
     EVP_CIPHER_CTX_cleanup(&ctx); 
    handleErrors("DInit"); 
    } 

    if (! EVP_DecryptUpdate (&ctx, outdata, &outlen1, indata, fsize)) 
    { 
     EVP_CIPHER_CTX_cleanup(&ctx); 
     handleErrors("DUpdate"); 
    } 

    if (! EVP_DecryptFinal_ex (&ctx, outdata + outlen1, &outlen2)) 
    { 

     EVP_CIPHER_CTX_cleanup(&ctx); 
     handleErrors("DFinal"); 
    } 

    EVP_CIPHER_CTX_cleanup(&ctx); 

    return outlen1+outlen2; 

} 

int isDirectory(char *path) 
{ 
    DIR *dir = NULL; 
    FILE *fin = NULL, *fout = NULL; 
    int enc_len = 0, dec_len = 0, fsize = 0, ksize = 0; 
    unsigned char *indata = NULL, *outdata = NULL; 
    char buff[BUFFER_SIZE], file_path[BUFFER_SIZE], cur_dir[BUFFER_SIZE]; 

    struct dirent *in_dir; 
    struct stat s; 

    if (NULL == (dir = opendir(path))) 
    { 
     printf ("ERROR: Failed to open the directory %s\n", path); 
     perror("cannot open."); 
     exit(1); 
    } 

    while (NULL != (in_dir = readdir(dir))) 
    { 

     if (!strcmp (in_dir->d_name, ".") || !strcmp(in_dir->d_name, "..")) 
      continue; 

     sprintf (buff, "%s/%s", path, in_dir->d_name); 

     if (-1 == stat(buff, &s)) 
     { 
      perror("stat"); 
      exit(1); 
     } 

     if (S_ISDIR(s.st_mode)) 
     { 

      isDirectory(buff); 
     } 
     else 
     { 
      strcpy(file_path, buff); 

      if (strstr(file_path, ".enc")) 
      { 

       /* File to be decrypted */ 

       fout = fopen(file_path,"rb"); 

       fseek (fout, 0L, SEEK_END); 
       fsize = ftell(fout); 
       fseek (fout, 0L, SEEK_SET); 

       indata = (char*)malloc(fsize); 

       fread (indata, sizeof(char), fsize, fout); 

       if (NULL == fout) 
       { 
        perror("Cannot open enc file: "); 
        return 1; 
       } 


       dec_len = decryptXML (indata, outdata, fsize); 
       outdata[dec_len] = '\0'; 
       printf ("%s\n", outdata); 
       fclose (fin); 
       fclose (fout); 

      } 
     } 
    } 



    closedir(dir); 
    freeMemory(outdata); 
    freeMemory(indata); 

    return 1; 
} 


int main(int argc, char *argv[]) 
{ 
    int result; 

    if (argc != 2) 
    { 
     printf ("Usage: <executable> path_of_the_files\n"); 
     return -1; 
    } 

    ERR_load_crypto_strings(); 
    OpenSSL_add_all_algorithms(); 
    OPENSSL_config(NULL); 

    /* Checking for the directory existance */ 

    result = isDirectory(argv[1]); 

    EVP_cleanup(); 
    ERR_free_strings(); 

    if (0 == result) 
     return 1; 
    else 
     return 0; 
} 

धन्यवाद।

+0

सीबीसी मोड केवल गोपनीयता प्रदान करता है, और आपको आमतौर पर सीबीसी मोड का सुरक्षित उपयोग करने के लिए एक मैक जोड़ना होगा। आपको शायद प्रमाणीकृत एन्क्रिप्शन का उपयोग करना चाहिए क्योंकि यह * दोनों * गोपनीयता और प्रामाणिकता प्रदान करता है। ओपनएसएसएल विकी पर [ईवीपी प्रमाणीकृत एन्क्रिप्शन और डिक्रिप्शन] देखें (https://wiki.openssl.org/index.php/EVP_Authenticated_Encryption_and_Decryption)। – jww

+0

अपना कोड सरलीकृत करें। सभी फाइल सिस्टम पढ़ने के साथ दूर करो। एक फ़ाइल एन्क्रिप्ट करें और उस फ़ाइल को डिक्रिप्ट करने का प्रयास करें। तब डिबगिंग बहुत आसान है। – adlag

+0

उत्तर के लिए धन्यवाद। क्या आपका मतलब है कि प्रोग्राम से सिस्टम कॉल का उपयोग? – Sai

उत्तर

4

मुझे लगता है कि आपके प्रोग्राम का उपयोग करके कमांड लाइन और डिक्रिप्शन का उपयोग करके एन्क्रिप्शन के लिए उपयोग की जाने वाली कुंजी और IV समान नहीं हैं।

कृपया ध्यान दें कि जब आप "-k" ("-K" से अलग) का उपयोग करते हैं, तो इनपुट को एक पासवर्ड के रूप में माना जाता है जिससे कुंजी प्राप्त की जाती है। आम तौर पर इस मामले में, "-iv" विकल्प की कोई आवश्यकता नहीं है क्योंकि दोनों कुंजी और पासवर्ड "-k" विकल्प के साथ दिए गए इनपुट से प्राप्त किए जाएंगे।

यह आपके प्रश्न से स्पष्ट नहीं है कि आप कैसे सुनिश्चित कर रहे हैं कि कुंजी और IV एन्क्रिप्शन और डिक्रिप्शन के बीच समान हैं।

मेरे सुझाव में, एन्क्रिप्शन के दौरान स्पष्ट रूप से कुंजी और चतुर्थ निर्दिष्ट करने के लिए "-K" और "-iv" विकल्प का बेहतर उपयोग करें और डिक्रिप्शन के लिए इसका उपयोग करें। यदि आपको "-k" का उपयोग करने की आवश्यकता है, तो एन्क्रिप्शन के लिए उपयोग की जाने वाली कुंजी और iv को मुद्रित करने के लिए "-p" विकल्प का उपयोग करें और अपने डिक्रिप्शन प्रोग्राम में इसका उपयोग करें।

अधिक जानकारी https://www.openssl.org/docs/manmaster/apps/enc.html

+0

धन्यवाद जय। हाँ! आप सही थे कि यह सही कुंजी और iv मान नहीं मिल रहा था। इसने आपके सुझाव के साथ एक सरल कार्यक्रम की कोशिश की (-K, -iv और -p विकल्प का उपयोग करके) और यह काम किया। मेरे पास एक और प्रश्न है। मैं इस आदेश ** openssl genrsa आउट key.pem 2048 ** मैं नीचे के रूप में इस कुंजी का उपयोग कर एक फ़ाइल एन्क्रिप्टेड है ** openssl ENC -aes-256-सीबीसी -इन rand_bytes का उपयोग कर एक निजी कुंजी जेनरेट किया है .c -out rand_bytes.enc -kfile key.pem ** अब सवाल है, मुझे ओपनएसएसएल ईवीपी एपीआई का उपयोग करके फ़ाइल को डिक्रिप्ट करने के लिए एक ही कुंजी पढ़नी है। क्या आप मुझे सुझाव दे सकते हैं, यह कैसे प्राप्त किया जा सकता है। धन्यवाद। – Sai

+0

@ साई: अगर यह आपके विशेष प्रश्न का उत्तर देता है, तो कृपया इसे इस धागे के उत्तर के रूप में चिह्नित करें। दूसरा उत्तर किसी भिन्न कारण के लिए उपयोगी है, लेकिन इसे अपनी विशिष्ट समस्या के उत्तर के रूप में चिह्नित करके, यह स्पष्ट करता है कि यह धागा दूसरे उत्तर से जुड़े किसी का डुप्लिकेट नहीं है। –

17

यह संदेश digital envelope routines: EVP_DecryptFInal_ex: bad decrypt पर प्राप्त किया जा सकता भी हो सकता है जब आप एन्क्रिप्ट और openssl का कोई असंगत संस्करणों के साथ डिक्रिप्ट।

मेरा मुद्दा यह था कि मैं विंडोज़ पर एन्क्रिप्ट कर रहा था जिसमें संस्करण 1.1.0 था और उसके बाद जेनेरिक लिनक्स सिस्टम पर 1.0.2 जी था।

यह एक बहुत ही उपयोगी त्रुटि संदेश नहीं है!

+15

यहां देखें: https://stackoverflow.com/a/39641378/284111 एमडी 5 से sha256 तक उन संस्करणों के बीच डिफ़ॉल्ट पाचन बदल गया है। कोई भी कमांड लाइन पर '-md sha256' या ​​'-md md5' के रूप में क्रमशः –

+1

@AndrewSavinykh धन्यवाद के रूप में डिफ़ॉल्ट डाइजेस्ट निर्दिष्ट कर सकता है! '-md md5' को जोड़ने से मेरे लिए समस्या हल हो गई। – mauvm

संबंधित मुद्दे