2011-12-06 69 views
2

我在使用OpenSSL Library(EVP api)的RSA解密中遇到問題。 這裏是我的密鑰生成在OpenSSL EVP api的EVP_OpenInit()中獲取RSA解密錯誤,C

#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

任何幫助,將不勝感激。 謝謝, Pawan

回答

3

你確定,你已經初始化變量eklen?

+0

是的,它是一個變量,我得到如下錯誤:140004942804648:錯誤:0407106B:LIB(4):FUNC(113):理由(107) :rsa_pk1.c:190: 140004942804648:error:04065072:lib(4):func(101):reason(114):rsa_eay.c:594: – Pawan

+1

在您的代碼片段中不是eklen = EVP_PKEY_size(pkey),這是一個(瑪比)正確的價值? –

+0

我已更新解密代碼,請通過它。這是一個變量。 – Pawan

2

我看你已經使用EVP_OpenInit(),EVP_OpenUpdate()EVP_OpenFinal()進行解密。所以我會假設你已經使用EVP_SealInit()EVP_SealUpdate()EVP_SealFinal()函數進行加密。

所以,如果你已經使用EVP_SealInit(),你必須通過地址(指針)eklen(請man EVP_SealInit)其中變量得到賦值。類似於您傳遞給EVP_OpenInit()eklen變量必須包含有效的密鑰長度。

以下是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"); 
... 
.. 
.