webBG - програмисти, машинно обучение, javascript, python, php, питам, говорим, публикации

Blowfish Шифроване и декриптиране на char буфери

Опитвам се да накарам функция bowfish да работи за прости буфери на char. Програмата се проваля, когато се опитвам да дешифрирам шифрован буфер и се проваля при повикването EVP_CipherFinal_ex().

#include <string.h> 
#include <openssl/evp.h> 
#include <openssl/buffer.h> 
#include <openssl/blowfish.h>
#include <openssl/evp.h>

int do_crypt(unsigned char *inbuf, int inlen, unsigned char *outbuf, int *outlen, int do_encrypt) { 
     outbuf=(unsigned char*) malloc(inlen+EVP_MAX_BLOCK_LENGTH); 
     int tmplen=0; 
     unsigned char key[] = "0123456789"; 
     unsigned char iv[] = "12345678"; 

     EVP_CIPHER_CTX ctx; 
     EVP_CIPHER_CTX_init(&ctx); 
     EVP_CipherInit_ex(&ctx, EVP_bf_cbc(), NULL, NULL, NULL, do_encrypt); 
     EVP_CIPHER_CTX_set_key_length(&ctx, 10); 
     EVP_CipherInit_ex(&ctx, NULL, NULL, key, iv, do_encrypt); 

     if(!EVP_CipherUpdate(&ctx, outbuf, outlen, inbuf, inlen)) { 
         /* Error */ 
         printf("* update failed *\n"); 
         EVP_CIPHER_CTX_cleanup(&ctx); 
         return 0; 
     } 

     int db=*outlen; 

     if(!EVP_CipherFinal_ex(&ctx, outbuf+db, &tmplen)) { 
         /* Error */ 
          ERR_print_errors_fp(stderr); 
         printf("* finalise failed *\n"); 
         EVP_CIPHER_CTX_cleanup(&ctx); 
         return 0; 
     } 


     (*outlen)=db+tmplen; 

     EVP_CIPHER_CTX_cleanup(&ctx); 

     return 1; 
} 
int main(int argc, char **argv) { 
     char *plain="ENCRYPT DECRYPT this string"; 
     int plain_len=strlen(plain); 
     unsigned char *cipher; 
     int cipher_len; 

     printf("***** ENCRYPT *****\n"); 
     if (!do_crypt((unsigned char*) plain, strlen(plain), cipher, &cipher_len, 1)) { 
         printf("failed to encrypt\n"); 
         return 1; 
     } 

     char *decrypt; 
     int decrypt_len; 
     printf("***** DECRYPT *****\n"); 
     if(!do_crypt(  cipher ,cipher_len , decrypt, &decrypt_len, 0)) { 
         printf("failed to decrypt\n"); 
         return 1; 
     }
 printf("decrypt=\"%s\"\n",decrypt); 
 printf("decrypt_len=%d\n",decrypt_len); 
     return 0; 
} 

всяка помощ ще бъде много ценена.

12.07.2014

  • И как се проваля? Какви грешки получавате? Какъв е очакваният резултат от вашата програма и какъв е действителният резултат? 13.07.2014
  • @JoachimPileborg Грешка при сегментиране '140536099350160:грешка:06065064:lib(6):func(101):reason(100):evp_enc.c:539:' 13.07.2014
  • Има и пример за това как да използвате интерфейсите EVP_* за криптиране и декриптиране в OpenSSL wiki. Вижте EVP симетрично криптиране и декриптиране. 13.07.2014
  • Ако някой се интересува, намерих решение тук! Благодаря на всички ви 16.07.2014

Отговори:


1

Имате два проблема: Първият е, че трябва не прехвърля резултата от malloc в C. Това е най-вероятната причина EVP_CipherUpdate да се срине.

Втората грешка е, че аргументите в C се предават по стойност, което означава, че се копират и функциите имат само копия на аргументите, предадени от извикващия. Това означава, че във функцията do_crypt, когато присвоявате на аргумента output, вие присвоявате само локалното копие във функцията, променливата cipher във функцията main няма да бъде променена.

Последният проблем може да бъде решен чрез имитиране на предаване по референция чрез предаване на указател към указателя и използване на оператора за адресиране & и оператора за дереференциране *:

/*                                     Note extra indirection */
/*                                                          | */
/*                                                          v */
int do_crypt(unsigned char *inbuf, int inlen, unsigned char **outbuf, int *outlen, int do_encrypt) {
    ...
    *output = malloc(...);
    ...
    if(!EVP_CipherUpdate(&ctx, *outbuf, outlen, inbuf, inlen)) { ... }
    ...
 }

След това го наричате така

do_crypt((unsigned char*) plain, strlen(plain), &cipher, &cipher_len, 1)
12.07.2014
  • проблемът е, когато се опитам да дешифрирам буферите на char и опитам това, което предложихте, но не работи и възникват толкова много грешки. 13.07.2014
  • @FlanAlflani Опитайте да поправите тези грешки (и възможни предупреждения). Ако не знаете как да коригирате всички грешки, публикувайте нов въпрос с модифицирания код и включете пълните и нередактирани регистрационни файлове за грешки и предупреждения. Също така не забравяйте, че във функцията трябва да помислите за предимство на оператор, когато добавяте дерефериращ оператор. Например имате напр. outbuf+db във вашия оригинален код, който трябва да промените на (*output)+db. 13.07.2014
  • @FlanAlflani Но наистина не виждам къде можете да получите грешки. Единственото нещо, което виждам, е предупреждение от повикването malloc, ако не следвате връзката в моя отговор и не прочетете защо не трябва да предавате malloc и как да поправите тези предупреждения. 13.07.2014
  • Нови материали

    Записване на грешки — Как да записвате грешки във вашето приложение, за да ги отстраните по-късно
    Записването на грешки е важна част от „обработването на грешки“. Накратко, когато възникнат определени грешки в програмите, вие искате да знаете за това. Това е особено важно при грешки. Ти..

    Кратко въведение в теорията на графите
    Кратко въведение в теорията на графите Втора част: внедряване на python на пълни графики В моята предишна статия въведох три основни концепции за графите: върхове, ръбове и тегла. В тази..

    Днес ще пиша за машинно обучение. Смятам се за ентусиаст, а не за експерт, така че имайте това предвид. С това казано, искам...
    Днес ще пиша за машинно обучение. Смятам се за ентусиаст, а не за експерт, така че имайте това предвид. С това казано искам да обясня защо машинното обучение има значение. За да бъда съвсем..

    Какво е структурно типизиране и как Typescript го използва в своя полза?
    Всички знаят тези дни, че „Typescript е строго синтактично надмножество на JavaScript и добавя незадължително статично въвеждане към езика.“. Но какво всъщност означава? Защо миграцията от..

    3 начина за премахване на дубликати от масив в Javascript
    Вие сте уеб разработчик? Програмист ли си? Тогава ще сте запознати с JavaScript и различните му вградени функции, методи и т.н. за различни реализации, проблеми и цели. Един от тези широко..

    Архитектура и обучение на конволюционни невронни мрежи (7 точки):
    Тази публикация предоставя подробности за архитектурата на Конволюционната невронна мрежа (CNN), функциите и обучението на всеки слой, завършвайки с резюме на обучението на CNN...

    Създайте разширение за Chrome с помощта на Angular
    Този урок е базиран на манифеста на разширението на chrome версия 3 (MV3), а също и на Angular версия 2+ (2, 3 и...). Ако не сте използвали манифест версия 3, можете да следвате този урок ,..