rsa_eay_private_encrypt

本文详细介绍了RSA加密过程中`rsa_eay_private_encrypt`函数涉及的BIGNUM结构,包括其内部成员d、top、dmax、neg和flags的含义。同时,还解析了BN_CTX上下文结构及其在大数运算中的作用。
部署运行你感兴趣的模型镜像


/* signing */
static int RSA_eay_private_encrypt(int flen, const unsigned char *from,
    unsigned char *to, RSA *rsa, int padding)
{
BIGNUM *f, *ret, *res;
int i,j,k,num=0,r= -1;
unsigned char *buf=NULL;
BN_CTX *ctx=NULL;
int local_blinding = 0;

/* blinding structure 共享时使用。 A non-NULL unblind

* instructs rsa_blinding_convert() and rsa_blinding_invert() to store
* the unblinding factor outside the blinding structure. */

BIGNUM *unblind = NULL;

BN_BLINDING *blinding = NULL;


if ((ctx=BN_CTX_new()) == NULL) goto err;


BN_CTX_start(ctx);
f   = BN_CTX_get(ctx);
ret = BN_CTX_get(ctx);
num = BN_num_bytes(rsa->n);
buf = OPENSSL_malloc(num);
if(!f || !ret || !buf)
{
RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT,ERR_R_MALLOC_FAILURE);
goto err;
}


switch (padding)
{
case RSA_PKCS1_PADDING:
i=RSA_padding_add_PKCS1_type_1(buf,num,from,flen);
break;
case RSA_X931_PADDING:
i=RSA_padding_add_X931(buf,num,from,flen);
break;
case RSA_NO_PADDING:
i=RSA_padding_add_none(buf,num,from,flen);
break;
case RSA_SSLV23_PADDING:
default:
RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT,RSA_R_UNKNOWN_PADDING_TYPE);
goto err;
}
if (i <= 0) goto err;


if (BN_bin2bn(buf,num,f) == NULL) goto err;

if (BN_ucmp(f, rsa->n) >= 0)
{
/* usually the padding functions would catch this */
RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT,RSA_R_DATA_TOO_LARGE_FOR_MODULUS);
goto err;
}


if (!(rsa->flags & RSA_FLAG_NO_BLINDING))
{
blinding = rsa_get_blinding(rsa, &local_blinding, ctx);
if (blinding == NULL)
{
RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT, ERR_R_INTERNAL_ERROR);
goto err;
}
}

if (blinding != NULL)
{
if (!local_blinding && ((unblind = BN_CTX_get(ctx)) == NULL))
{
RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT,ERR_R_MALLOC_FAILURE);
goto err;
}
if (!rsa_blinding_convert(blinding, f, unblind, ctx))
goto err;
}


if ( (rsa->flags & RSA_FLAG_EXT_PKEY) ||
((rsa->p != NULL) &&
(rsa->q != NULL) &&
(rsa->dmp1 != NULL) &&
(rsa->dmq1 != NULL) &&
(rsa->iqmp != NULL)) )

if (!rsa->meth->rsa_mod_exp(ret, f, rsa, ctx)) goto err;
}
else
{
BIGNUM local_d;
BIGNUM *d = NULL;

if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME))
{
BN_init(&local_d);
d = &local_d;
BN_with_flags(d, rsa->d, BN_FLG_CONSTTIME);
}
else
d= rsa->d;


if (rsa->flags & RSA_FLAG_CACHE_PUBLIC)
if(!BN_MONT_CTX_set_locked(&rsa->_method_mod_n, CRYPTO_LOCK_RSA, rsa->n, ctx))
goto err;


if (!rsa->meth->bn_mod_exp(ret,f,d,rsa->n,ctx,
rsa->_method_mod_n)) goto err;
}


if (blinding)
if (!rsa_blinding_invert(blinding, ret, unblind, ctx))
goto err;


if (padding == RSA_X931_PADDING)
{
BN_sub(f, rsa->n, ret);
if (BN_cmp(ret, f))
res = f;
else
res = ret;
}
else
res = ret;


/* put in leading 0 bytes if the number is less than the
* length of the modulus */
j=BN_num_bytes(res);
i=BN_bn2bin(res,&(to[num-j]));
for (k=0; k<(num-i); k++)
to[k]=0;


r=num;
err:
if (ctx != NULL)
{
BN_CTX_end(ctx);
BN_CTX_free(ctx);
}
if (buf != NULL)
{
OPENSSL_cleanse(buf,num);
OPENSSL_free(buf);
}
return(r);
}


static int RSA_eay_private_decrypt(int flen, const unsigned char *from,
    unsigned char *to, RSA *rsa, int padding)
{
BIGNUM *f, *ret;
int j,num=0,r= -1;
unsigned char *p;
unsigned char *buf=NULL;
BN_CTX *ctx=NULL;
int local_blinding = 0;
/* Used only if the blinding structure is shared. A non-NULL unblind
* instructs rsa_blinding_convert() and rsa_blinding_invert() to store
* the unblinding factor outside the blinding structure. */
BIGNUM *unblind = NULL;
BN_BLINDING *blinding = NULL;


if((ctx = BN_CTX_new()) == NULL) goto err;
BN_CTX_start(ctx);
f   = BN_CTX_get(ctx);
ret = BN_CTX_get(ctx);
num = BN_num_bytes(rsa->n);
buf = OPENSSL_malloc(num);
if(!f || !ret || !buf)
{
RSAerr(RSA_F_RSA_EAY_PRIVATE_DECRYPT,ERR_R_MALLOC_FAILURE);
goto err;
}


/* This check was for equality but PGP does evil things
* and chops off the top '0' bytes */
if (flen > num)
{
RSAerr(RSA_F_RSA_EAY_PRIVATE_DECRYPT,RSA_R_DATA_GREATER_THAN_MOD_LEN);
goto err;
}


/* make data into a big number */
if (BN_bin2bn(from,(int)flen,f) == NULL) goto err;


if (BN_ucmp(f, rsa->n) >= 0)
{
RSAerr(RSA_F_RSA_EAY_PRIVATE_DECRYPT,RSA_R_DATA_TOO_LARGE_FOR_MODULUS);
goto err;
}


if (!(rsa->flags & RSA_FLAG_NO_BLINDING))
{
blinding = rsa_get_blinding(rsa, &local_blinding, ctx);
if (blinding == NULL)
{
RSAerr(RSA_F_RSA_EAY_PRIVATE_DECRYPT, ERR_R_INTERNAL_ERROR);
goto err;
}
}

if (blinding != NULL)
{
if (!local_blinding && ((unblind = BN_CTX_get(ctx)) == NULL))
{
RSAerr(RSA_F_RSA_EAY_PRIVATE_DECRYPT,ERR_R_MALLOC_FAILURE);
goto err;
}
if (!rsa_blinding_convert(blinding, f, unblind, ctx))
goto err;
}


/* do the decrypt */
if ( (rsa->flags & RSA_FLAG_EXT_PKEY) ||
((rsa->p != NULL) &&
(rsa->q != NULL) &&
(rsa->dmp1 != NULL) &&
(rsa->dmq1 != NULL) &&
(rsa->iqmp != NULL)) )
{
if (!rsa->meth->rsa_mod_exp(ret, f, rsa, ctx)) goto err;
}
else
{
BIGNUM local_d;
BIGNUM *d = NULL;

if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME))
{
d = &local_d;
BN_with_flags(d, rsa->d, BN_FLG_CONSTTIME);
}
else
d = rsa->d;


if (rsa->flags & RSA_FLAG_CACHE_PUBLIC)
if (!BN_MONT_CTX_set_locked(&rsa->_method_mod_n, CRYPTO_LOCK_RSA, rsa->n, ctx))
goto err;
if (!rsa->meth->bn_mod_exp(ret,f,d,rsa->n,ctx,
rsa->_method_mod_n))
 goto err;
}


if (blinding)
if (!rsa_blinding_invert(blinding, ret, unblind, ctx))
goto err;


p=buf;
j=BN_bn2bin(ret,p); /* j is only used with no-padding mode */


switch (padding)
{
case RSA_PKCS1_PADDING:
r=RSA_padding_check_PKCS1_type_2(to,num,buf,j,num);
break;
#ifndef OPENSSL_NO_SHA
        case RSA_PKCS1_OAEP_PADDING:
       r=RSA_padding_check_PKCS1_OAEP(to,num,buf,j,num,NULL,0);
                break;
#endif
  case RSA_SSLV23_PADDING:
r=RSA_padding_check_SSLv23(to,num,buf,j,num);
break;
case RSA_NO_PADDING:
r=RSA_padding_check_none(to,num,buf,j,num);
break;
default:
RSAerr(RSA_F_RSA_EAY_PRIVATE_DECRYPT,RSA_R_UNKNOWN_PADDING_TYPE);
goto err;
}
if (r < 0)
RSAerr(RSA_F_RSA_EAY_PRIVATE_DECRYPT,RSA_R_PADDING_CHECK_FAILED);


err:
if (ctx != NULL)
{
BN_CTX_end(ctx);
BN_CTX_free(ctx);
}
if (buf != NULL)
{
OPENSSL_cleanse(buf,num);
OPENSSL_free(buf);
}
return(r);
}


/* signature verification */
static int RSA_eay_public_decrypt(int flen, const unsigned char *from,
    unsigned char *to, RSA *rsa, int padding)
{
BIGNUM *f,*ret;
int i,num=0,r= -1;
unsigned char *p;
unsigned char *buf=NULL;
BN_CTX *ctx=NULL;


if (BN_num_bits(rsa->n) > OPENSSL_RSA_MAX_MODULUS_BITS)
{
RSAerr(RSA_F_RSA_EAY_PUBLIC_DECRYPT, RSA_R_MODULUS_TOO_LARGE);
return -1;
}


if (BN_ucmp(rsa->n, rsa->e) <= 0)
{
RSAerr(RSA_F_RSA_EAY_PUBLIC_DECRYPT, RSA_R_BAD_E_VALUE);
return -1;
}


/* for large moduli, enforce exponent limit */
if (BN_num_bits(rsa->n) > OPENSSL_RSA_SMALL_MODULUS_BITS)
{
if (BN_num_bits(rsa->e) > OPENSSL_RSA_MAX_PUBEXP_BITS)
{
RSAerr(RSA_F_RSA_EAY_PUBLIC_DECRYPT, RSA_R_BAD_E_VALUE);
return -1;
}
}

if((ctx = BN_CTX_new()) == NULL) goto err;
BN_CTX_start(ctx);
f = BN_CTX_get(ctx);
ret = BN_CTX_get(ctx);
num=BN_num_bytes(rsa->n);
buf = OPENSSL_malloc(num);
if(!f || !ret || !buf)
{
RSAerr(RSA_F_RSA_EAY_PUBLIC_DECRYPT,ERR_R_MALLOC_FAILURE);
goto err;
}


/* This check was for equality but PGP does evil things
* and chops off the top '0' bytes */
if (flen > num)
{
RSAerr(RSA_F_RSA_EAY_PUBLIC_DECRYPT,RSA_R_DATA_GREATER_THAN_MOD_LEN);
goto err;
}


if (BN_bin2bn(from,flen,f) == NULL) goto err;


if (BN_ucmp(f, rsa->n) >= 0)
{
RSAerr(RSA_F_RSA_EAY_PUBLIC_DECRYPT,RSA_R_DATA_TOO_LARGE_FOR_MODULUS);
goto err;
}


if (rsa->flags & RSA_FLAG_CACHE_PUBLIC)
if (!BN_MONT_CTX_set_locked(&rsa->_method_mod_n, CRYPTO_LOCK_RSA, rsa->n, ctx))
goto err;


if (!rsa->meth->bn_mod_exp(ret,f,rsa->e,rsa->n,ctx,
rsa->_method_mod_n)) goto err;


if ((padding == RSA_X931_PADDING) && ((ret->d[0] & 0xf) != 12))
if (!BN_sub(ret, rsa->n, ret)) goto err;


p=buf;
i=BN_bn2bin(ret,p);


switch (padding)
{
case RSA_PKCS1_PADDING:
r=RSA_padding_check_PKCS1_type_1(to,num,buf,i,num);
break;
case RSA_X931_PADDING:
r=RSA_padding_check_X931(to,num,buf,i,num);
break;
case RSA_NO_PADDING:
r=RSA_padding_check_none(to,num,buf,i,num);
break;
default:
RSAerr(RSA_F_RSA_EAY_PUBLIC_DECRYPT,RSA_R_UNKNOWN_PADDING_TYPE);
goto err;
}
if (r < 0)
RSAerr(RSA_F_RSA_EAY_PUBLIC_DECRYPT,RSA_R_PADDING_CHECK_FAILED);


err:
if (ctx != NULL)
{
BN_CTX_end(ctx);
BN_CTX_free(ctx);
}
if (buf != NULL)
{
OPENSSL_cleanse(buf,num);
OPENSSL_free(buf);
}
return(r);


代码解析:

1. BIGNUM *f , *ret ;

bignum  --->   typedef struct bignum_st BIGNUM;  -----> struct bignum_st

{

BN_ULONG  *d;

int  top;

int  dmax;

int  neg;

int  flags;

}

各项意义如下:

d: BN_ULONG,数组指针首地址,大数就存放在这里面,不过是倒放的。比如,用户要存放的

大数为12345678000(通过BN_bin2bn放入),则d的内容如下:

0x300x30 0x30 0x38 0x37 0x36 0x35 0x34 0x33 0x32 0x31;

top:用来指明大数占多少个BN_ULONG空间,上例中top为3。

dmax:d数组的大小。

neg:是否为负数,如果为1,则是负数,为0,则为正数。

flags:用于存放一些标记,比如flags含有BN_FLG_STATIC_DATA时,表明d的内存是静态分配的;

含有BN_FLG_MALLOCED时,d的内存是动态分配的。


2. BN_CTX *ctx = NULL;   ---------》  typedef struct bignum_ctx BN_CTX;   ------->    struct  bignum_ctx

{

BN_POOL pool; //大数句柄

BN_STACK  stack; //堆栈帧

unsigned int  used; //分配的大数

int  err_stack; //

int  too_many;

}

typedef struct bignum_pool

{

BN_POOL_ITEM  *head, *current,  *tail; // BN_POOL_ITEM ---> typedef  struct bignum_bool;

unsigned  used, size;

}  

typedef  struct bignum_ctx_stack

{

unsigned int *indexes;

unsigned int depth, size;

} BN_STACK;



您可能感兴趣的与本文相关的镜像

Kotaemon

Kotaemon

AI应用

Kotaemon 是由Cinnamon 开发的开源项目,是一个RAG UI页面,主要面向DocQA的终端用户和构建自己RAG pipeline

<think>好的,我需要帮助用户找到OpenSSL3.4.1中替代RSA_public_encryptRSA_private_encrypt的函数。首先,我得回忆一下OpenSSL3.x版本的变化。记得从3.0开始,OpenSSL引入了Provider概念,并逐渐淘汰了一些旧的API,推荐使用EVP(Envelope)接口来进行加密操作。用户提到的RSA_public_encryptRSA_private_encrypt这两个函数属于低级API,可能在3.x中被标记为弃用。根据官方文档,替代方案应该是使用EVP_PKEY_encrypt和EVP_PKEY_decrypt,这些函数属于高级的EVP接口,支持多种算法,包括RSA。接下来,我需要确认在3.4.1版本中,这些替代函数是否确实适用。查阅OpenSSL的更新日志或迁移指南,发现官方确实建议使用EVP接口代替旧的RSA_*函数。例如,RSA_public_encrypt可以用EVP_PKEY_encrypt替代,而RSA_private_encrypt可能对应EVP_PKEY_sign,因为私钥加密通常用于签名。另外需要注意填充方式的设置。旧函数中通过参数指定填充,如RSA_PKCS1_PADDING,现在需要在EVP操作中通过EVP_PKEY_CTX_set_rsa_padding来设置。例如,使用EVP_PKEY_CTX_new_id和相应的设置函数来配置上下文。还要考虑示例代码的正确性,确保用户能够理解如何迁移他们的现有代码。可能需要提供一个简单的例子,展示如何使用EVP接口进行加密和解密,包括错误处理的部分,比如检查返回值。最后,提醒用户关于编译时的依赖和链接库的变化,确保他们正确链接了OpenSSL3.x的库,并处理可能出现的弃用警告。同时,建议用户参考官方文档和迁移指南以获取更详细的信息。</think>在OpenSSL 3.4.1中,`RSA_public_encrypt`和`RSA_private_encrypt`已被新的EVP接口替代,这是OpenSSL 3.0之后推行"Provider"架构的重要改变。具体替代方案如下: ### 1. 函数替代关系 - **原函数**:`RSA_public_encrypt` **替代函数**:`EVP_PKEY_encrypt` ```c int EVP_PKEY_encrypt(EVP_PKEY_CTX *ctx, unsigned char *out, size_t *outlen, const unsigned char *in, size_t inlen); ``` 用于公钥加密操作,支持RSA、SM2等算法[^1] - **原函数**:`RSA_private_encrypt` **替代函数**:`EVP_PKEY_sign` ```c int EVP_PKEY_sign(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen, const unsigned char *tbs, size_t tbslen); ``` 用于签名生成(即私钥加密操作)[^2] ### 2. 典型使用流程 以公钥加密为例: ```c EVP_PKEY_CTX *ctx = EVP_PKEY_CTX_new(pkey, NULL); if (!ctx) handle_error(); if (EVP_PKEY_encrypt_init(ctx) <= 0) handle_error(); if (EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_PADDING) <= 0) handle_error(); // 设置填充方式 size_t outlen; if (EVP_PKEY_encrypt(ctx, NULL, &outlen, in, inlen) <= 0) handle_error(); unsigned char *out = OPENSSL_malloc(outlen); if (EVP_PKEY_encrypt(ctx, out, &outlen, in, inlen) <= 0) handle_error(); ``` ### 3. 关键变化说明 - **上下文管理**:需通过`EVP_PKEY_CTX`管理操作上下文 - **填充方式设置**:使用`EVP_PKEY_CTX_set_rsa_padding`指定填充模式(如`RSA_PKCS1_PADDING`) - **内存管理**:输出缓冲区需通过`OPENSSL_malloc`分配 - **错误处理**:所有EVP函数返回1表示成功,0或负数表示失败 ### 4. 兼容性提示 - 旧代码需要添加头文件: ```c #include <openssl/evp.h> ``` - 编译时需要链接`-lssl -lcrypto` - 启用严格模式时需定义宏: ```c #define OPENSSL_API_COMPAT 30000 #define OPENSSL_NO_DEPRECATED ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值