【问题标题】:Remove dirt in result of decrypt with openssl (C Language)使用openssl(C语言)去除解密结果中的污垢
【发布时间】:2014-09-18 14:57:42
【问题描述】:

经过研究,我认为是时候寻求帮助了,因为我不明白问题出在哪里。 我正在使用 OpenSSL 进行加密和解密。 我修复了代码,以便更清楚谁可能愿意帮助我。 它基本上由三个函数组成:generate_key_pair、example_one、example_two 在示例中,我加载文件的内容,密码学家,将内容放入变量中,解密变量的内容,将结果放入另一个变量中。 一切都很完美。 在示例二中,我携带文件的内容,密码学家,将内容放入文件,加载文件内容,解密。 在这种情况下,当我解密时会出现一个我无法确定如何避免的“污垢”。 我把这几个词放在代码中,我用来编译的命令和得到的结果。 已经很感谢大家了。

编译:

gcc -std=c99 source\RSA\RSA.c source\RSA\applink.c -Isource\RSA\include -Lsource\RSA\lib\openssl -leay32 -lssleay32 -o build\rsa.exe

代码:

#include <openssl/rsa.h>
#include <openssl/pem.h>
#include <openssl/err.h>
#include <stdio.h>
#include <string.h>

int generate_key_pair(int KEY_LENGTH, char *PRIVATE_KEY_FILENAME, char *PUBLIC_KEY_FILENAME)
{    
    FILE *KEY_FILE;
    RSA *KEY_PAIR;  
    int RESULT = 0;

    KEY_PAIR = RSA_generate_key(KEY_LENGTH, 17, NULL, NULL);    
    KEY_FILE = fopen(PRIVATE_KEY_FILENAME,"w");
    RESULT = PEM_write_RSAPrivateKey(KEY_FILE, KEY_PAIR, NULL, NULL, 0, NULL, NULL);
    fclose(KEY_FILE);
    KEY_FILE = fopen(PUBLIC_KEY_FILENAME,"w");
    RESULT = (RESULT && PEM_write_RSAPublicKey(KEY_FILE, KEY_PAIR));
    fclose(KEY_FILE);
    return RESULT;
}

void example_one(int KEY_LENGTH, char *PRIVATE_KEY_FILENAME, char *PUBLIC_KEY_FILENAME)
{   
    printf("--- EXAMPLE 1: BEGIN---\r\n\r\n");
    RSA *PUBLIC_KEY = NULL; 
    RSA *PRIVATE_KEY = NULL;
    FILE *KEY_FILE;

    KEY_FILE = fopen(PUBLIC_KEY_FILENAME, "r"); 
    PUBLIC_KEY = PEM_read_RSAPublicKey(KEY_FILE,NULL,NULL,NULL);

    KEY_FILE = fopen(PRIVATE_KEY_FILENAME, "r");    
    PRIVATE_KEY = PEM_read_RSAPrivateKey(KEY_FILE,NULL,NULL,NULL);

    int PUBLIC_KEY_SIZE = RSA_size(PUBLIC_KEY);
    int PRIVATE_KEY_SIZE = RSA_size(PRIVATE_KEY);

    FILE *INPUT_FILE = fopen("BUFFER.TXT", "r");        
    fseek(INPUT_FILE, 0, SEEK_END);
    int INPUT_FILE_SIZE = ftell(INPUT_FILE);
    rewind(INPUT_FILE);
    char *FILE_CONTENTS = malloc(KEY_LENGTH/8);
    fread(FILE_CONTENTS, sizeof(char), INPUT_FILE_SIZE, INPUT_FILE);
    fclose(INPUT_FILE);
    FILE_CONTENTS[INPUT_FILE_SIZE] = '\0';

    printf("ORIGINAL FILE_CONTENTS=\r\n%s\r\n\r\n",FILE_CONTENTS);

    char *ENCRYPTED = NULL;
    char *DECRYPTED = NULL;

    ENCRYPTED = malloc(PUBLIC_KEY_SIZE);
    RSA_public_encrypt(strlen(FILE_CONTENTS), (unsigned char*)FILE_CONTENTS, (unsigned char*)ENCRYPTED, PUBLIC_KEY, RSA_PKCS1_OAEP_PADDING);

    printf("ENCRYPTED=\r\n%s\r\n\r\n",ENCRYPTED);   

    DECRYPTED = malloc(PRIVATE_KEY_SIZE);
    RSA_private_decrypt(PRIVATE_KEY_SIZE, (unsigned char*)ENCRYPTED, (unsigned char*)DECRYPTED, PRIVATE_KEY, RSA_PKCS1_OAEP_PADDING);

    printf("DECRYPTED=\r\n%s\r\n\r\n",DECRYPTED);

    free(ENCRYPTED);
    ENCRYPTED = NULL;
    free(DECRYPTED);
    DECRYPTED = NULL;
    printf("--- EXAMPLE 1: END---\r\n\r\n");
}

void example_two(int KEY_LENGTH, char *PRIVATE_KEY_FILENAME, char *PUBLIC_KEY_FILENAME)
{
    printf("--- EXAMPLE 2: BEGIN---\r\n\r\n");
    RSA *PUBLIC_KEY = NULL; 
    RSA *PRIVATE_KEY = NULL;    
    FILE *KEY_FILE;

    KEY_FILE = fopen(PUBLIC_KEY_FILENAME, "r"); 
    PUBLIC_KEY = PEM_read_RSAPublicKey(KEY_FILE,NULL,NULL,NULL);

    KEY_FILE = fopen(PRIVATE_KEY_FILENAME, "r");    
    PRIVATE_KEY = PEM_read_RSAPrivateKey(KEY_FILE,NULL,NULL,NULL);

    int PUBLIC_KEY_SIZE = RSA_size(PUBLIC_KEY);
    int PRIVATE_KEY_SIZE = RSA_size(PRIVATE_KEY);

    FILE *INPUT_FILE = fopen("BUFFER.TXT", "r");        
    fseek(INPUT_FILE, 0, SEEK_END);
    int INPUT_FILE_SIZE = ftell(INPUT_FILE);
    rewind(INPUT_FILE);
    char *FILE_CONTENTS = malloc(KEY_LENGTH/8);
    fread(FILE_CONTENTS, sizeof(char), INPUT_FILE_SIZE, INPUT_FILE);
    fclose(INPUT_FILE);
    FILE_CONTENTS[INPUT_FILE_SIZE] = '\0';

    printf("ORIGINAL FILE_CONTENTS=\r\n%s\r\n\r\n",FILE_CONTENTS);

    char *ENCRYPTED = NULL;
    char *DECRYPTED = NULL;

    ENCRYPTED = malloc(PUBLIC_KEY_SIZE);
    RSA_public_encrypt(strlen(FILE_CONTENTS), (unsigned char*)FILE_CONTENTS, (unsigned char*)ENCRYPTED, PUBLIC_KEY, RSA_PKCS1_OAEP_PADDING);

    printf("ENCRYPTED=\r\n%s\r\n\r\n",ENCRYPTED);   

    FILE *FILE_OUT = fopen("BUFFER_ENCRYPTED.TXT", "w");
    fwrite(ENCRYPTED,sizeof(char),strlen(ENCRYPTED),FILE_OUT);
    fclose(FILE_OUT);
    free(ENCRYPTED);
    ENCRYPTED = NULL;

    FILE *FILE_IN = fopen("BUFFER_ENCRYPTED.TXT", "r");     
    fseek(FILE_IN, 0, SEEK_END);
    INPUT_FILE_SIZE = ftell(FILE_IN);
    rewind(FILE_IN);
    FILE_CONTENTS = malloc(PRIVATE_KEY_SIZE);
    fread(FILE_CONTENTS, sizeof(char), PRIVATE_KEY_SIZE, FILE_IN);
    fclose(FILE_IN);

    printf("ENCRYPTED FILE_CONTENTS=\r\n%s\r\n\r\n",FILE_CONTENTS);

    DECRYPTED = malloc(PRIVATE_KEY_SIZE);
    RSA_private_decrypt(PRIVATE_KEY_SIZE, (unsigned char*)FILE_CONTENTS, (unsigned char*)DECRYPTED, PRIVATE_KEY, RSA_PKCS1_OAEP_PADDING);

    printf("DECRYPTED=\r\n%s\r\n\r\n",DECRYPTED);   

    FILE_OUT = fopen("BUFFER_DECRYPTED.TXT", "w");
    fwrite(DECRYPTED,1,strlen(DECRYPTED),FILE_OUT);
    fclose(FILE_OUT);
    free(DECRYPTED);
    DECRYPTED = NULL;

    free(ENCRYPTED);
    ENCRYPTED = NULL;
    free(DECRYPTED);
    DECRYPTED = NULL;
    printf("--- EXAMPLE 2: END---\r\n\r\n");
}

int main(void) {
    int KEY_LENGTH = 2048;
    char *PRIVATE_KEY_FILENAME = "KPRIVATE.PEM";
    char *PUBLIC_KEY_FILENAME = "KPUBLIC.PEM";

    generate_key_pair(KEY_LENGTH,PRIVATE_KEY_FILENAME,PUBLIC_KEY_FILENAME);

    example_one(KEY_LENGTH,PRIVATE_KEY_FILENAME,PUBLIC_KEY_FILENAME);

    example_two(KEY_LENGTH,PRIVATE_KEY_FILENAME,PUBLIC_KEY_FILENAME);

    return 0;
}

结果:

--- EXAMPLE 1: BEGIN---

ORIGINAL FILE_CONTENTS=
It is a test!

ENCRYPTED=
◄4ƒþ×^ÖÜ_)'┘ó(¿o╚¡Õßçxô╝♂:9·╗♂l│¿,<õС+¨═è╣╚IÙL¶,*A1´çØ↔ß%ém¦e  sø¥Qþ¯█‼◄Ð]röwK╠
áWÁ]Úl╗Fv├Æ((Ó*║&^

DECRYPTED=
It is a test!

--- EXAMPLE 1: END---

--- EXAMPLE 2: BEGIN---

ORIGINAL FILE_CONTENTS=
It is a test!

ENCRYPTED=
îþ┘éÑ▬ı;Í5±òM¬ƒ¢ÈkÖ╣┌┬ÆbE☺ã`)[ıó▄■fÞ*ªÄ╚↕ 3É^¾µS86qÜz▬a↑zh▓j´¶È)ë├╬ƒC♂Ë·âÃxÛ╝°ÿ@
Å◄ÈJ~\÷a¼?m▒Ít@♀█ñ¼Ä:£z┤ÀýøGöÞ╩30☼→┘G┬$Ã╩ô°Z‗¢re8►♥k'♫W
ês=ðã;Gfd¬♀@¾þw╚¢Ó_lºóó.├╣ß8┤¼yÝ╚þ┬☼¦è+zP"│┴Isd19ģǹ×^╣ñ0‼▀Zƒ¾↑}▬.Æãáý·│yCb?ù©u
_|ıƒÀ

ENCRYPTED FILE_CONTENTS=
îþ┘éÑ▬ı;Í5±òM¬ƒ¢ÈkÖ╣┌┬ÆbE☺ã`)[ıó▄■fÞ*ªÄ╚↕ 3É^¾µS86qÜz▬a↑zh▓j´¶È)ë├╬ƒC♂Ë·âÃxÛ╝°ÿ@
Å◄ÈJ~\÷a¼?m▒Ít@♀█ñ¼Ä:£z┤ÀýøGöÞ╩30☼→┘G┬$Ã╩ô°Z‗¢re8►♥k'♫W
ês=ðã;Gfd¬♀@¾þw╚¢Ó_lºóó.├╣ß8┤¼yÝ╚þ┬☼¦è+zP"│┴Isd19ģǹ×^╣ñ0‼▀Zƒ¾↑}▬.Æãáý·│yCb?ù©u
_|ıƒÀ

DECRYPTED=
It is a test!òM¬ƒ¢ÈkÖ╣┌┬ÆbE☺ã`)[ıó▄■fÞ*ªÄ╚↕ 3É^¾µS86qÜz▬a↑zh▓j´¶È)ë├╬ƒC♂Ë·âÃxÛ╝°
Å◄ÈJ~\÷a¼?m▒Ít@♀█ñ¼Ä:£z┤ÀýøGöÞ╩30☼→┘G┬$Ã╩ô°Z‗¢re8►♥k'♫W
ês=ðã;Gfd¬♀@¾þw╚¢Ó_lºóó.├╣ß8┤¼yÝ╚þ┬☼¦è+zP"│┴Isd19ģǹ×^╣ñ0‼▀Zƒ¾↑}▬.Æãáý·│yCb?ù©u
_¶ƒÀ,

--- EXAMPLE 2: END---

【问题讨论】:

    标签: c encryption openssl


    【解决方案1】:

    我在 freenode 的 irc #c 频道上找到的正确答案:

    [kadoban] renatokrause:您将 DECRYPTED 视为零终止 细绳。它不是。您需要使用的返回值 RSA_private_decrypted,告诉你它输出了多少数据

    最终代码:

    #include <openssl/rsa.h>
    #include <openssl/pem.h>
    #include <openssl/err.h>
    #include <stdio.h>
    #include <string.h>
    
    int generate_key_pair(int KEY_LENGTH, char *PRIVATE_KEY_FILENAME, char *PUBLIC_KEY_FILENAME)
    {    
        FILE *KEY_FILE;
        RSA *KEY_PAIR;  
        int RESULT = 0;
    
        KEY_PAIR = RSA_generate_key(KEY_LENGTH, 17, NULL, NULL);    
        KEY_FILE = fopen(PRIVATE_KEY_FILENAME,"w");
        RESULT = PEM_write_RSAPrivateKey(KEY_FILE, KEY_PAIR, NULL, NULL, 0, NULL, NULL);
        fclose(KEY_FILE);
        KEY_FILE = fopen(PUBLIC_KEY_FILENAME,"w");
        RESULT = (RESULT && PEM_write_RSAPublicKey(KEY_FILE, KEY_PAIR));
        fclose(KEY_FILE);
        return RESULT;
    }
    
    void example_one(int KEY_LENGTH, char *PRIVATE_KEY_FILENAME, char *PUBLIC_KEY_FILENAME)
    {   
        printf("--- EXAMPLE 1: BEGIN---\r\n\r\n");
        RSA *PUBLIC_KEY = NULL; 
        RSA *PRIVATE_KEY = NULL;
        FILE *KEY_FILE;
    
        KEY_FILE = fopen(PUBLIC_KEY_FILENAME, "r"); 
        PUBLIC_KEY = PEM_read_RSAPublicKey(KEY_FILE,NULL,NULL,NULL);
    
        KEY_FILE = fopen(PRIVATE_KEY_FILENAME, "r");    
        PRIVATE_KEY = PEM_read_RSAPrivateKey(KEY_FILE,NULL,NULL,NULL);
    
        int PUBLIC_KEY_SIZE = RSA_size(PUBLIC_KEY);
        int PRIVATE_KEY_SIZE = RSA_size(PRIVATE_KEY);
    
        FILE *INPUT_FILE = fopen("BUFFER.TXT", "r");        
        fseek(INPUT_FILE, 0, SEEK_END);
        int INPUT_FILE_SIZE = ftell(INPUT_FILE);
        rewind(INPUT_FILE);
        char *FILE_CONTENTS = malloc(KEY_LENGTH/8);
        fread(FILE_CONTENTS, sizeof(char), INPUT_FILE_SIZE, INPUT_FILE);
        fclose(INPUT_FILE);
        FILE_CONTENTS[INPUT_FILE_SIZE] = '\0';
    
        printf("ORIGINAL FILE_CONTENTS=\r\n%s\r\n\r\n",FILE_CONTENTS);
    
        char *ENCRYPTED = NULL;
        char *DECRYPTED = NULL;
    
        ENCRYPTED = malloc(PUBLIC_KEY_SIZE);
        RSA_public_encrypt(strlen(FILE_CONTENTS), (unsigned char*)FILE_CONTENTS, (unsigned char*)ENCRYPTED, PUBLIC_KEY, RSA_PKCS1_OAEP_PADDING);
    
        printf("ENCRYPTED=\r\n%s\r\n\r\n",ENCRYPTED);   
    
        DECRYPTED = malloc(PRIVATE_KEY_SIZE);
        RSA_private_decrypt(PRIVATE_KEY_SIZE, (unsigned char*)ENCRYPTED, (unsigned char*)DECRYPTED, PRIVATE_KEY, RSA_PKCS1_OAEP_PADDING);
    
        printf("DECRYPTED=\r\n%s\r\n\r\n",DECRYPTED);
    
        free(ENCRYPTED);
        ENCRYPTED = NULL;
        free(DECRYPTED);
        DECRYPTED = NULL;
        printf("--- EXAMPLE 1: END---\r\n\r\n");
    }
    
    void example_two(int KEY_LENGTH, char *PRIVATE_KEY_FILENAME, char *PUBLIC_KEY_FILENAME)
    {
        printf("--- EXAMPLE 2: BEGIN---\r\n\r\n");
        RSA *PUBLIC_KEY = NULL; 
        RSA *PRIVATE_KEY = NULL;    
        FILE *KEY_FILE;
    
        KEY_FILE = fopen(PUBLIC_KEY_FILENAME, "r"); 
        PUBLIC_KEY = PEM_read_RSAPublicKey(KEY_FILE,NULL,NULL,NULL);
    
        KEY_FILE = fopen(PRIVATE_KEY_FILENAME, "r");    
        PRIVATE_KEY = PEM_read_RSAPrivateKey(KEY_FILE,NULL,NULL,NULL);
    
        int PUBLIC_KEY_SIZE = RSA_size(PUBLIC_KEY);
        int PRIVATE_KEY_SIZE = RSA_size(PRIVATE_KEY);
    
        FILE *INPUT_FILE = fopen("BUFFER.TXT", "r");        
        fseek(INPUT_FILE, 0, SEEK_END);
        int INPUT_FILE_SIZE = ftell(INPUT_FILE);
        rewind(INPUT_FILE);
        char *FILE_CONTENTS = malloc(KEY_LENGTH/8);
        fread(FILE_CONTENTS, sizeof(char), INPUT_FILE_SIZE, INPUT_FILE);
        fclose(INPUT_FILE);
        FILE_CONTENTS[INPUT_FILE_SIZE] = '\0';
    
        printf("ORIGINAL FILE_CONTENTS=\r\n%s\r\n\r\n",FILE_CONTENTS);
    
        char *ENCRYPTED = NULL;
        char *DECRYPTED = NULL;
    
        ENCRYPTED = malloc(PUBLIC_KEY_SIZE);
        RSA_public_encrypt(strlen(FILE_CONTENTS), (unsigned char*)FILE_CONTENTS, (unsigned char*)ENCRYPTED, PUBLIC_KEY, RSA_PKCS1_OAEP_PADDING);
    
        printf("ENCRYPTED=\r\n%s\r\n\r\n",ENCRYPTED);   
    
        FILE *FILE_OUT = fopen("BUFFER_ENCRYPTED.TXT", "w");
        fwrite(ENCRYPTED,sizeof(char),strlen(ENCRYPTED),FILE_OUT);
        fclose(FILE_OUT);
        free(ENCRYPTED);
        ENCRYPTED = NULL;
    
        FILE *FILE_IN = fopen("BUFFER_ENCRYPTED.TXT", "r");     
        fseek(FILE_IN, 0, SEEK_END);
        INPUT_FILE_SIZE = ftell(FILE_IN);
        rewind(FILE_IN);
        FILE_CONTENTS = malloc(PRIVATE_KEY_SIZE);
        fread(FILE_CONTENTS, sizeof(char), PRIVATE_KEY_SIZE, FILE_IN);
        fclose(FILE_IN);
        FILE_CONTENTS[INPUT_FILE_SIZE] = '\0';
        printf("ENCRYPTED FILE_CONTENTS=\r\n%s\r\n\r\n",FILE_CONTENTS);
    
        DECRYPTED = malloc(PRIVATE_KEY_SIZE);
        int DECRYPTED_SIZE = RSA_private_decrypt(PRIVATE_KEY_SIZE, (unsigned char*)FILE_CONTENTS, (unsigned char*)DECRYPTED, PRIVATE_KEY, RSA_PKCS1_OAEP_PADDING);
    
        printf("DECRYPTED=\r\n%s\r\n\r\n",DECRYPTED);   
    
        FILE_OUT = fopen("BUFFER_DECRYPTED.TXT", "w");
        fwrite(DECRYPTED,1,DECRYPTED_SIZE,FILE_OUT);
        fclose(FILE_OUT);
        free(DECRYPTED);
        DECRYPTED = NULL;
    
        free(ENCRYPTED);
        ENCRYPTED = NULL;
        free(DECRYPTED);
        DECRYPTED = NULL;
        printf("--- EXAMPLE 2: END---\r\n\r\n");
    }
    
    int main(void) {
        int KEY_LENGTH = 2048;
        char *PRIVATE_KEY_FILENAME = "KPRIVATE.PEM";
        char *PUBLIC_KEY_FILENAME = "KPUBLIC.PEM";
    
        generate_key_pair(KEY_LENGTH,PRIVATE_KEY_FILENAME,PUBLIC_KEY_FILENAME);
    
        example_one(KEY_LENGTH,PRIVATE_KEY_FILENAME,PUBLIC_KEY_FILENAME);
    
        example_two(KEY_LENGTH,PRIVATE_KEY_FILENAME,PUBLIC_KEY_FILENAME);
    
        return 0;
    }
    

    【讨论】:

    • 放弃了我的答案,因为告诉你字符串没有终止显然还不够(我试过)。您可能会发现使用此方法加密 245+ 字符长的文件非常有趣。结果可能会让您大吃一惊。
    • 如果您使用 pkcs1_oaep 或常规 pkcs1 填充,它实际上小于模数大小。 see this question 了解更多信息。值得您花时间简要介绍一下,包括替代方案(使用 AES 对称密钥对数据进行两阶段加密,然后讨论用于 AES 密钥的 RSA)。祝你好运。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-01-08
    • 1970-01-01
    • 2013-07-15
    • 2018-07-23
    • 1970-01-01
    相关资源
    最近更新 更多