C PEM“读取”RSA“公开密钥错误”;应为“公钥”;

C PEM“读取”RSA“公开密钥错误”;应为“公钥”;,c,linux,encryption,openssl,rsa,C,Linux,Encryption,Openssl,Rsa,我正在尝试实现OpenSSL 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() {

我正在尝试实现OpenSSL 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);
    BIO *bio_out = NULL;
    FILE *fp;

    if (!ctx)
    {
        perror("Error in CTX \n");
    }
    if (EVP_PKEY_keygen_init(ctx) <= 0)
    {
        perror("Error in EVP_PKEY_keygen_init \n");
    }
    if (EVP_PKEY_CTX_set_rsa_keygen_bits(ctx, 2048) <= 0)
    {
        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");
    if ((bio_out = BIO_new_fp(fp, BIO_NOCLOSE)) == NULL)
    {
        perror("Error in new BIO \n");
    }

    BIO_set_flags(bio_out, BIO_FLAGS_WRITE);
    EVP_PKEY_print_private(bio_out,pkey,5, NULL);

    fclose(fp);
    BIO_free(bio_out);

    fp = fopen(PUBFILE, "w");
    if ((bio_out = BIO_new_fp(fp, BIO_NOCLOSE)) == NULL)
    {
        perror("Error in new BIO \n");
    }

    BIO_set_flags(bio_out, BIO_FLAGS_WRITE);
    EVP_PKEY_print_public(bio_out,pkey,5, NULL);

    fclose(fp);
    BIO_free(bio_out);

    return 0;
}
以下是我用于加密的代码:

#include <stdio.h> 
#include <stdlib.h> 

#include <openssl/evp.h> 
#include <openssl/pem.h> 
#include <openssl/rsa.h> 
#include <openssl/err.h> 

#include <arpa/inet.h> /* For htonl() */ 

int do_evp_seal(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]; 

    if (!PEM_read_RSA_PUBKEY(rsa_pkey_file, &rsa_pkey, NULL, NULL)) 
    { 
        fprintf(stderr, "Error loading RSA Public Key File.\n"); 
        // here I am getting this error:
        // 140121481717416:error:0906D06C:lib(9):func(109):reason(108):pem_lib.c:696:Expecting: PUBLIC KEY

        ERR_print_errors_fp(stderr); 
        retval = 2; 
        goto out; 
    }

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

    if (!EVP_SealInit(&ctx, EVP_aes_128_cbc(), &ek, &eklen, iv, &pkey, 1)) 
    { 
        fprintf(stderr, "EVP_SealInit: failed.\n"); 
        retval = 3; 
        goto out_free; 
    } 

    /* First we write out the encrypted key length, then the encrypted key, 
     * then the iv (the IV length is fixed by the cipher we have chosen). 
     */ 

    eklen_n = htonl(eklen); 
    if (fwrite(&eklen_n, sizeof eklen_n, 1, out_file) != 1) 
    { 
        perror("output file"); 
        retval = 5; 
        goto out_free; 
    } 
    if (fwrite(ek, eklen, 1, out_file) != 1) 
    { 
        perror("output file"); 
        retval = 5; 
        goto out_free; 
    } 
    if (fwrite(iv, EVP_CIPHER_iv_length(EVP_aes_128_cbc()), 1, out_file) != 1) 
    { 
        perror("output file"); 
        retval = 5; 
        goto out_free; 
    } 

    /* Now we process the input file and write the encrypted data to the 
     * output file. */ 

    while ((len = fread(buffer, 1, sizeof buffer, in_file)) > 0) 
    { 
        if (!EVP_SealUpdate(&ctx, buffer_out, &len_out, buffer, len)) 
        { 
            fprintf(stderr, "EVP_SealUpdate: 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_SealFinal(&ctx, buffer_out, &len_out)) 
    { 
        fprintf(stderr, "EVP_SealFinal: 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; 
} 

int main(int argc, char *argv[]) 
{ 
    FILE *rsa_pkey_file; 
    int rv; 

    rsa_pkey_file = fopen("pub.pem", "rb"); 
    if (!rsa_pkey_file) 
    { 
        fprintf(stderr, "Error loading PEM RSA Public Key File.\n"); 
        exit(2); 
    } 

    rv = do_evp_seal(rsa_pkey_file, stdin, stdout); 

    fclose(rsa_pkey_file); 
    return rv; 
}
#包括
#包括
#包括
#包括
#包括
#包括
#对于htonl()*/
int do_evp_印章(文件*rsa_pkey_文件,文件*in_文件,文件*out_文件)
{ 
int-retval=0;
RSA*RSA_pkey=NULL;
EVP_PKEY*PKEY=EVP_PKEY_new();
执行副总裁;
无符号字符缓冲区[4096];
无符号字符缓冲区输出[4096+EVP最大IV长度];
尺寸透镜;
内列夫;
无符号字符*ek;
内埃克伦;
uint32_t eklen_n;
无符号字符iv[EVP_MAX_iv_LENGTH];
if(!PEM_read_RSA_PUBKEY(RSA_pkey_文件和RSA_pkey,NULL,NULL))
{ 
fprintf(stderr,“加载RSA公钥文件时出错。\n”);
//这里我得到了一个错误:
//140121481717416:错误:0906D06C:lib(9):func(109):原因(108):pem_lib.c:696:预期:公钥
错误打印错误fp(stderr);
retval=2;
出去;
}
EVP_CIPHER_CTX_init(&CTX);
ek=malloc(执行副总裁职位大小(职位大小));
如果(!EVP_SealInit(&ctx,EVP_aes_128_cbc(),&ek,&eklen,iv,&pkey,1))
{ 
fprintf(标准,“EVP_SealInit:失败。\n”);
retval=3;
自由出去;
} 
/*首先我们写出加密密钥的长度,然后是加密密钥,
*然后是iv(iv长度由我们选择的密码固定)。
*/ 
eklen_n=htonl(eklen);
if(fwrite(&eklen\u n,eklen\u n的大小,1,out\u文件)!=1)
{ 
perror(“输出文件”);
retval=5;
自由出去;
} 
if(写入(ek,eklen,1,输出文件)!=1)
{ 
perror(“输出文件”);
retval=5;
自由出去;
} 
if(fwrite(iv,EVP_CIPHER_iv_length(EVP_aes_128_cbc()),1,out_file)!=1)
{ 
perror(“输出文件”);
retval=5;
自由出去;
} 
/*现在我们处理输入文件并将加密数据写入
*输出文件。*/
而((len=fread(buffer,1,sizeof buffer,in_file))>0)
{ 
如果(!EVP\U SealUpdate(&ctx,buffer\U out,&len\U out,buffer,len))
{ 
fprintf(标准,“EVP_SealUpdate:失败。\n”);
retval=3;
自由出去;
} 
if(写入(缓冲区输出、镜头输出、1、输出文件)!=1)
{ 
perror(“输出文件”);
retval=5;
自由出去;
} 
} 
如果(ferror(在文件中))
{ 
perror(“输入文件”);
retval=4;
自由出去;
} 
如果(!EVP\u SealFinal(&ctx、缓冲区输出和透镜输出))
{ 
fprintf(标准,“EVP_SealFinal:失败。\n”);
retval=3;
自由出去;
} 
if(写入(缓冲区输出、镜头输出、1、输出文件)!=1)
{ 
perror(“输出文件”);
retval=5;
自由出去;
} 
免费外出:
免费执行副总裁(PKEY);
免费(ek);
输出:
返回返回;
} 
int main(int argc,char*argv[])
{ 
文件*rsa_pkey_文件;
int-rv;
rsa_pkey_file=fopen(“pub.pem”、“rb”);
如果(!rsa_pkey_文件)
{ 
fprintf(stderr,“加载PEM RSA公钥文件时出错。\n”);
出口(2);
} 
rv=do_evp_密封件(rsa_pkey_文件、标准数据、标准数据);
fclose(rsa_pkey_文件);
返回rv;
}

为什么
PEM\u read\u RSA\u PUBKEY
返回
错误:需要公钥?

好的,我发现我自己写了
PEM\u write\u bio\u PUBKEY(bio\u out,pkey)而不是
EVP\u PKEY\u print\u public(bio\u out,PKEY)

#include <stdio.h> 
#include <stdlib.h> 

#include <openssl/evp.h> 
#include <openssl/pem.h> 
#include <openssl/rsa.h> 
#include <openssl/err.h> 

#include <arpa/inet.h> /* For htonl() */ 

int do_evp_seal(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]; 

    if (!PEM_read_RSA_PUBKEY(rsa_pkey_file, &rsa_pkey, NULL, NULL)) 
    { 
        fprintf(stderr, "Error loading RSA Public Key File.\n"); 
        // here I am getting this error:
        // 140121481717416:error:0906D06C:lib(9):func(109):reason(108):pem_lib.c:696:Expecting: PUBLIC KEY

        ERR_print_errors_fp(stderr); 
        retval = 2; 
        goto out; 
    }

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

    if (!EVP_SealInit(&ctx, EVP_aes_128_cbc(), &ek, &eklen, iv, &pkey, 1)) 
    { 
        fprintf(stderr, "EVP_SealInit: failed.\n"); 
        retval = 3; 
        goto out_free; 
    } 

    /* First we write out the encrypted key length, then the encrypted key, 
     * then the iv (the IV length is fixed by the cipher we have chosen). 
     */ 

    eklen_n = htonl(eklen); 
    if (fwrite(&eklen_n, sizeof eklen_n, 1, out_file) != 1) 
    { 
        perror("output file"); 
        retval = 5; 
        goto out_free; 
    } 
    if (fwrite(ek, eklen, 1, out_file) != 1) 
    { 
        perror("output file"); 
        retval = 5; 
        goto out_free; 
    } 
    if (fwrite(iv, EVP_CIPHER_iv_length(EVP_aes_128_cbc()), 1, out_file) != 1) 
    { 
        perror("output file"); 
        retval = 5; 
        goto out_free; 
    } 

    /* Now we process the input file and write the encrypted data to the 
     * output file. */ 

    while ((len = fread(buffer, 1, sizeof buffer, in_file)) > 0) 
    { 
        if (!EVP_SealUpdate(&ctx, buffer_out, &len_out, buffer, len)) 
        { 
            fprintf(stderr, "EVP_SealUpdate: 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_SealFinal(&ctx, buffer_out, &len_out)) 
    { 
        fprintf(stderr, "EVP_SealFinal: 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; 
} 

int main(int argc, char *argv[]) 
{ 
    FILE *rsa_pkey_file; 
    int rv; 

    rsa_pkey_file = fopen("pub.pem", "rb"); 
    if (!rsa_pkey_file) 
    { 
        fprintf(stderr, "Error loading PEM RSA Public Key File.\n"); 
        exit(2); 
    } 

    rv = do_evp_seal(rsa_pkey_file, stdin, stdout); 

    fclose(rsa_pkey_file); 
    return rv; 
}