在C中用于RSA解密的OpenSSL EVP api的EVP_OpenInit()中获取错误

时间:2011-12-06 13:05:22

标签: c encryption openssl rsa public-key-encryption

我在使用OpenSSL库(EVP api)进行RSA解密时遇到问题。 这是我生成密钥的代码

#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;
}

加密:

我使用了这个link

解密:

   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 个答案:

答案 0 :(得分:3)

您是否完全确定,您已初始化变量eklen?

答案 1 :(得分:2)

我发现您已使用EVP_OpenInit()EVP_OpenUpdate()EVP_OpenFinal()进行解密。因此,我假设您已使用EVP_SealInit()EVP_SealUpdate()EVP_SealFinal()函数进行加密。

因此,如果您使用过EVP_SealInit(),则必须已将地址(指针)传递给eklen(请检查man EVP_SealInit),其中变量将获得分配的值。与此类似,传递给eklen的{​​{1}}变量必须包含有效的密钥长度。

以下是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()