Получение ошибки в EVP_OpenInit () API OpenPL EVP для расшифровки RSA, в C - PullRequest
2 голосов
/ 06 декабря 2011

У меня проблема с расшифровкой RSA с использованием библиотеки OpenSSL (EVP api). Вот мой код для генерации ключей

#include <stdio.h>
#include <openssl/evp.h>
#include <openssl/rsa.h>
#include <openssl/bio.h>
#include <openssl/pem.h>

#define SECFILE "sec.pem"
#define PUBFILE "pub.pem"

int main()
{

    EVP_PKEY_CTX *ctx;
    EVP_PKEY *pkey = NULL;
    ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_RSA, NULL);
    FILE *fp;

    if (!ctx)
    {
        /* Error occurred */
        perror("Error in CTX \n");

    }
    if (EVP_PKEY_keygen_init(ctx) <= 0)
    {
        /* Error */
        perror("Error in EVP_PKEY_keygen_init \n");
    }
    if (EVP_PKEY_CTX_set_rsa_keygen_bits(ctx, 2048) <= 0)
    {
        /* Error */
        perror("Error in EVP_PKEY_CTX_set_rsa_keygen_bits \n");
    }
    /* Generate key */
    if (EVP_PKEY_keygen(ctx, &pkey) <= 0)
    {   
        /* Error */
        perror("Error in EVP_PKEY_keygen \n");

    }


    fp = fopen(SECFILE, "w");
    PEM_write_PrivateKey(fp, pkey, NULL,NULL, 0,0, NULL);
    fclose(fp);

    fp = fopen(PUBFILE, "w");
    PEM_write_PUBKEY(fp,pkey);
    fclose(fp);


    return 0;
}

Для шифрования:

Я использовал эту ссылку

Для расшифровки:

   int do_evp_open(FILE *rsa_pkey_file, FILE *in_file, FILE *out_file) 
{ 
    int retval = 0; 
    RSA *rsa_pkey = NULL; 
    EVP_PKEY *pkey = EVP_PKEY_new(); 
    EVP_CIPHER_CTX ctx; 
    unsigned char buffer[4096]; 
    unsigned char buffer_out[4096 + EVP_MAX_IV_LENGTH]; 
    size_t len; 
    int len_out; 
    unsigned char *ek; 
    int eklen ; 
    uint32_t eklen_n; 
    unsigned char iv[EVP_MAX_IV_LENGTH] = {122,205,106,192,4,183,69,176,84,28,214,226,220,140,86,174}; 


    /// Read RSA Private Key 
    if (PEM_read_RSAPrivateKey(rsa_pkey_file, &rsa_pkey, NULL, NULL) == NULL) 
    { 
        fprintf(stderr, "Error loading RSA Private Key File.\n"); 
        ERR_print_errors_fp(stderr); 
        retval = -2; 
        goto out; 
    } 


    /// Assign RSA key to EVP key
    if (!EVP_PKEY_assign_RSA(pkey, rsa_pkey)) 
    { 
        fprintf(stderr, "EVP_PKEY_assign_RSA: failed.\n"); 
        retval = -3; 
        goto out; 
    }

    EVP_CIPHER_CTX_init(&ctx); 

    ek = malloc( EVP_PKEY_size(pkey)); 



    if (!EVP_OpenInit(&ctx, EVP_aes_128_cbc(), ek, eklen, iv,pkey)) 
    { 
        fprintf(stderr, "EVP_OpenInit: failed.\n"); 
       ERR_print_errors_fp(stderr); /// Prints error of occured in Openssl  
        retval = -3; 
        goto out_free; 
    } 




    while ((len = fread(buffer, 1, sizeof buffer, in_file)) > 0) 
    { 
        if (!EVP_OpenUpdate(&ctx, buffer_out, &len_out, buffer, len)) 
        { 
            fprintf(stderr, "EVP_OpenUpdate: failed.\n"); 
            retval = 3; 
            goto out_free; 
        } 

        if (fwrite(buffer_out, len_out, 1, out_file) != 1) 
        { 
            perror("output file"); 
            retval = -5; 
            goto out_free; 
        } 
    } 

    if (ferror(in_file)) 
    { 
        perror("input file"); 
        retval = -4; 
        goto out_free; 
    } 

    if (!EVP_OpenFinal(&ctx, buffer_out, &len_out)) 
    { 
        fprintf(stderr, "EVP_OpenFinal: failed.\n"); 
        retval = - 3; 
        goto out_free; 
    } 

    if (fwrite(buffer_out, len_out, 1, out_file) != 1) 
    { 
        perror("output file"); 
        retval = -5; 
        goto out_free; 
    } 

    out_free: 
    EVP_PKEY_free(pkey); 
    free(ek); 

    out: 
    return retval; 
} 

Мои личные и открытые ключи:

-----BEGIN PRIVATE KEY-----
MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDj+g6m7KY5zK8z
FZ/MKFySr1ZB+n0b3GjhMUcUDn5S9N7oyoCzkOVVa7gl0jTI8dwCFVAy8693Rq+i
AT7dUTLViT9V8GkX9r0yFcppt5uc2YgI5aOOTvmQKQe08FSZ7QbviEL25MNnBfB1
wpd+mJN3nb0hkeo7x2IZD/ZVfs+TmOG9mHbQR8b1XcxEDoLx3aX1J8Eix1pN7YK6
nDAFm984Ho+PCz1aGl/TnDl3b90X5HXGHiD6uNDHokZ+th8B6AeFFRlkWlQd0w2R
e/EEZ36p4TQOHSc3sSUw6pen0N8YmBNZksBEr1vsZvYkKtRKCfy0fXtL4iqKzcgJ
ocos+Z6nAgMBAAECggEBALlWDdlYpF5y76/JEaso2PGLR8XFvTYMPttsc0tz6PDK
D/oSvwS8dCS4uPFObgk6ztCGwTda8rg2KAy9lHzaSUheFrZoBxgrSG5SVscRNJoU
IsqQ3iGQRMUVBiXsB+tHTg8nqMENA2pa4rzpoL2Tjrd87kg/VryYgEC9wFaLDHgB
FaXJJlaeuTBQXV7Ga9pg+KF1Kv91/q3T62Um0ggSajFpX15x6sLIo5EWm0DGksn0
chQeiEs33e8fHil95g0nXK+hXOMnMvbAln/eOCGktO4JnPTjicAA7iKliCsLiaeZ
t5Czscv/8AVlBAISGJcE8ASM+AbalXtnoOK6W+dv0gkCgYEA/cPi7U8bJ0tlvxF3
3vc8V7uzuAgKtOKQet1spQtAoi343ZoSyFHQEwO5PMmtB56/mk3+/mDpoKTQo0oK
f5COIlzW+PIMQCroalpJe+ZcY/PS8SPoOY39yiX4WQchgac01R0Qf6XDAOfyfZ9d
MZTtDgpkx/oyfRTzxI7D9SZUqZ0CgYEA5fwH5uwmc0fsIw3tl3pHHOK9g78Rs6XE
0feXplBCzx+qaEtAK1Jp1nMX/PmN575i3UN3dii9YV8v9geTf+hytpQd/TbrvsSY
Py9j95XYN75Z5TAsWnZbZr/gTdZSz0yObb/9GzxBipp+EHCEOSS0RF8u9XHlM9bC
0agB4VZKqBMCgYByIjxaR44K6lpkyVKEseYt/3ohd1x5Zr1cxWIsCReU2eBoqvdv
qXxQUQhrUrnEB55dpF7fwm7Rlc9Q4eg+36FNyzvU0+i2o5XM37bVRxKe0fc6BdBY
sohG9zTvtclYKwAUKfJVtxQxwCDMZ3Te7ACCpCIX32v93gKVkTCJfift8QKBgHZ9
PAEAZ+r7AjEpSuDBMgQy2ZsYBOG+pUHcQzh/n3wg/2XOZ1gqlLbVA2XlmPPtxffj
e5fX84JITWh/jMHYm8lvVGgSNLFLjnj3TJTRkd1eZ+hJwoA0/HBaqRDRPEbrVXI7
+QZgLBBh+lMz9RuPyoRzWblBHepwWl00JwvWro4bAoGBAKFAXVzbx74JM6wzr9H5
TusTwOM5mf/I1TkCq1Dd5n1vDVfrkNokZ2LfJWqiQHLZj2rGxSQSVjIsVaBmEDTZ
ob8duUsbkYQe4dToHFHcBO+akBtULC4HWv/D4pPVoyAE7WJBJBw0vl1sA15kiXBu
HBXffOzN/Erqvp90HLtefpMp
-----END PRIVATE KEY-----


-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4/oOpuymOcyvMxWfzChc
kq9WQfp9G9xo4TFHFA5+UvTe6MqAs5DlVWu4JdI0yPHcAhVQMvOvd0avogE+3VEy
1Yk/VfBpF/a9MhXKabebnNmICOWjjk75kCkHtPBUme0G74hC9uTDZwXwdcKXfpiT
d529IZHqO8diGQ/2VX7Pk5jhvZh20EfG9V3MRA6C8d2l9SfBIsdaTe2CupwwBZvf
OB6Pjws9Whpf05w5d2/dF+R1xh4g+rjQx6JGfrYfAegHhRUZZFpUHdMNkXvxBGd+
qeE0Dh0nN7ElMOqXp9DfGJgTWZLARK9b7Gb2JCrUSgn8tH17S+Iqis3ICaHKLPme
pwIDAQAB
-----END PUBLIC KEY-----

Я получаю сообщение об ошибке, пока EVP_OpenInit:

140004942804648:error:0407106B:lib(4):func(113):reason(107):rsa_pk1.c:190: 140004942804648:error:04065072:lib(4):func(101):reason(114):rsa_eay.c:594

Любая помощь будет оценена. Спасибо, Паван

Ответы [ 2 ]

3 голосов
/ 15 декабря 2011

Вы абсолютно уверены, что инициализировали переменную эклен?

2 голосов
/ 28 декабря 2011

Я вижу, вы использовали EVP_OpenInit(), EVP_OpenUpdate() и EVP_OpenFinal() для расшифровки.Итак, я собираюсь предположить, что вы использовали EVP_SealInit(), EVP_SealUpdate() и EVP_SealFinal() функции для шифрования.

Так что, если вы использовали EVP_SealInit(), вы должны были передать адрес (указатель) eklen (пожалуйста, отметьте man EVP_SealInit), где переменная получает присвоенное значение.Аналогично тому, что переменная eklen, которую вы передаете EVP_OpenInit(), должна содержать допустимую длину ключа.

Ниже приведено описание man EVP_OpenInit.

EVP_OpenInit() initializes a cipher context ctx for decryption with cipher type. It decrypts the encrypted symmetric key of length ekl bytes passed in the ek parameter using the private key priv. The IV is supplied in the iv parameter.

Я не уверен, но вам нужно использовать функцию EVP_PKEY_size() вв этом случае, чтобы получить длину ключа.

Например (в коде расшифровки):

....
..
. 
EVP_CIPHER_CTX_init(&ctx); 
ek = malloc( EVP_PKEY_size(pkey)); 

/* Add the following line */
eklen = EVP_PKEY_size(pkey);

if (!EVP_OpenInit(&ctx, EVP_aes_128_cbc(), ek, eklen, iv,pkey)) 
{ 
    fprintf(stderr, "EVP_OpenInit: failed.\n"); 
...
..
.
...