【问题标题】:How to use OpenSSL 3.0 RSA in C?如何在 C 中使用 OpenSSL 3.0 RSA?
【发布时间】:2021-09-07 04:25:29
【问题描述】:

我想简单地加密和解密一些数据。自 OpenSSL 3.0 以来,许多旧方法已被弃用。
公私钥生成代码:

void generateKeys(){
    EVP_PKEY*pkey=EVP_RSA_gen(1024);
    if(pkey==NULL){
        fprintf(stderr,"error: rsa gen\n");
        ERR_print_errors_fp(stderr);
        return;
    }
    FILE*fp=fopen("public.txt","wt");
    if(fp!=NULL){
        PEM_write_PUBKEY(fp,pkey);
        fclose(fp);
    }else{
        perror("file error");
    }
    fp=fopen("private.txt","wt");
    if(fp!=NULL){
        PEM_write_PrivateKey(fp,pkey,NULL,NULL,0,NULL,NULL);
        fclose(fp);
    }else{
        perror("file error");
    }
    EVP_PKEY_free(pkey);
}

加密函数:

uchar*encrypt(uchar*src,uint len,int*length){
    FILE*fp=fopen("public.txt","r");
    if(fp==NULL){
        perror("file error");
        return NULL;
    }
    EVP_PKEY*pkey;
    pkey=PEM_read_PUBKEY(fp,NULL,NULL,NULL);
    fclose(fp);
    if(pkey==NULL){
        fprintf(stderr,"error: read publics key\n");
        return NULL;
    }
    EVP_PKEY_CTX*ctx=EVP_PKEY_CTX_new(pkey,NULL);
    EVP_PKEY_encrypt_init(ctx);
    uchar*dst=(uchar*)malloc(2048);
    size_t outl;
    if(!EVP_PKEY_encrypt(ctx,dst,&outl,src,(size_t)len)){
        fprintf(stderr,"error: encrypt\n");
        EVP_PKEY_free(pkey);
        free(dst);
        return NULL;
    }
    int len2=outl;
    EVP_PKEY_free(pkey);
    EVP_PKEY_CTX_free(ctx);
    BIO_dump_fp(stdout,dst,len2);
    printf("len: %d, len2: %d\n",len,len2);
    if(length!=NULL){
        *length=len2;
    }
    return dst;
}

解密函数:

uchar*decrypt(uchar*src,int len){
    FILE*fp=fopen("private.txt","r");
    if(fp==NULL){
        perror("file error");
        return NULL;
    }
    EVP_PKEY*pkey=PEM_read_PrivateKey(fp,NULL,NULL,NULL);
    fclose(fp);
    if(pkey==NULL){
        fprintf(stderr,"error: read private key\n");
        return NULL;
    }
    EVP_PKEY_CTX*ctx=EVP_PKEY_CTX_new(pkey,NULL);
    EVP_PKEY_decrypt_init(ctx);
    uchar*dst=(uchar*)malloc(2048);
    size_t outl;
    size_t inl=len;
    if(!EVP_PKEY_decrypt(ctx,dst,&outl,src,inl)){
        fprintf(stderr,"error: decrypt\n");
        free(dst);
        dst=NULL;
    }else{
        BIO_dump_fp(stdout,dst,(int)outl);
        printf("len: %d, outl: %lld\n",len,outl);
    } 
    EVP_PKEY_free(pkey);
    EVP_PKEY_CTX_free(ctx);
    return dst;
}

函数EVP_PKEY_decrypt总是返回0,有什么问题?
官方文档建议使用EVP模块。所以我尝试使用这个模块来加密一些数据。默认的 RSA 填充是 RSA_PKCS1_PADDING。但是貌似没有完整的EVP使用RSA的教程。

【问题讨论】:

  • “解密数据时总是失败。”不是一个好的错误描述。通常您应该在调用init 之后设置填充模式,例如OAEP。请注意,RSA 模式只允许对一定数量的数据进行加密;之后,您应该使用混合密码系统(例如 RSA OAEP + AES GCM)。

标签: c encryption openssl rsa


【解决方案1】:

当我在解密函数中将代码size_t outl更改为size_t outl=2048时,效果很好。

【讨论】:

    猜你喜欢
    • 2022-12-01
    • 2014-07-26
    • 1970-01-01
    • 2021-09-28
    • 2014-05-16
    • 1970-01-01
    • 2011-08-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多