【发布时间】: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