rsa_eay_private_encrypt_qssjh0356的博客-程序员宅基地

技术标签: openssl 学习  


/* 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;



版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/qssjh0356/article/details/11651799

智能推荐

Linux 重定向_zeroonetwothree的博客-程序员宅基地

&lt; :输入重定向&gt; :输出重定向&gt;&gt; :输出重定向,进行追加,不会覆盖之前内容&lt;&lt; :标准输入来自命令行的一对分隔号的中间内容.需求:向文件内自动输入一些内容,举一个简单的例子。cat &lt;&lt;EOF&gt; out.txt&gt;This is a sample&gt;second line&gt;EOF通过上面的重定向知识,我们可以知道 cat 命令获取了来自自定义分隔符‘EOF’中的内容作为标准输入,然后标准输出重定位到 out.txt

IOS中Json解析的四种方法_zhengxiuchen86的博客-程序员宅基地

作为一种轻量级的数据交换格式,json正在逐步取代xml,成为网络数据的通用格式。 有的json代码格式比较混乱,可以使用此“http://www.bejson.com/”网站来进行JSON

Docker 从入门到精通(三)一 网络配置_流風餘韻的博客-程序员宅基地

docker 是Linux下面的容器技术,是目前最火的开源技术之一,上次我们了解了docker的本地仓库的搭建,今天我们介绍下docker的容器配置步骤,网络的一些配置。

DataList,Repeater分页问题可以采用三种方式解决: _haojialin的博客-程序员宅基地

DataList,Repeater分页问题可以采用三种方式解决: 1.采用第三方开发的控件如:ASpNetPager,用了感觉效果还不错 2.使用SqlDataAdapter.Fill(DataSet,起始记录位置,最大填充记录数,"表名")这个重载函数,好像是这个,有可能我写的有问题,一时记不清楚了 3.或者采用.NET提供的一个支持分页的类 PagedDataSource  下面是一个使用 P

记事本保存功能c++_系统小技巧:用好新版Windows 10记事本_Respect yourself的博客-程序员宅基地

Windows 10系统中最没出息的软件也许要数“记事本”了,十多年来几乎没见有啥长进,直到Windows 10到来时也不例外。不过,从1809版开始,Windows 10自带的记事本却多了几个非常方便的功能。也许这几个功能容易被我们所忽视,但不用也可惜了。1. 不开浏览器 关键词即时在线搜索以往我们在用记事本软件编辑一篇文档时,如果碰到有疑惑的词语需要上网搜索,免不了先打开网络浏览器,复制或输入...

OpenFeign学习(四):OpenFeign的方法同步请求执行_openfeign 同步 异步_布碗的博客-程序员宅基地

说明在上篇博文《OpenFeign学习(三):OpenFeign配置生成代理对象》中,我对OpenFeign的整体工作流程做了简单的介绍,并且通过源码,介绍学习了OpenFeign配置创建代理对象的原理。在本篇博文中,我将继续通过源码对OpenFeign的方法请求工作流程的原理进行介绍学习。正文在阅读请求部分的源码前,我们先回顾下上篇博文的内容,包括OpenFeign的整体工作流程图和配置创...

随便推点

Access数据库SQL语句操作_weixin_30782293的博客-程序员宅基地

笔记疑问:ACCESS中一直没能找到用sql语句更改列名、创建约束、设置默认值。经过测试,建表时也不能同时设置默认值。如下列建表语句会报错(但把第三句的default 0去掉就能执行):create table test (id counter,name char(20) not null,age integer not null default 0,notes memo,pri...

Source Insight设置总结_huangpeiwen的博客-程序员宅基地

<br />      在网上搜索了一些关于Source Insight的设置技巧,把这些结果给总结下来:<br />      1、背景色选择<br />    要改变背景色Options->preference->windows background->color设置背景色,最好使用原始的配置,不要修改颜色。<br />2、解决字符等宽对齐问题。<br />    SIS默认字体是VERDANA,很漂亮。这网页上应该也是用的VERDANA字体。但由于美观的缘故,VERDANA字体是不等宽的。比如下面两行

BAPI 记录_bapi_po_getdetail_西柚e的博客-程序员宅基地

采购订单BAPI_PO_CREATE1采购订单创建交货单BAPI_OUTB_DELIVERY_CREATE_STO根据凭证类型获取TVAK-VBTYP 判断要创建的SO类别 不同类别调用不同BAPI创建SOBAPI_SALESORDER_CREATEFROMDAT2创建SO退货BAPI_CUSTOMERRETURN_CREATE创建SO借贷项凭证SD_SALES...

HTML/CSS: Make a Ring Menu 环形菜单_前端环绕菜单_小威威__的博客-程序员宅基地

制作一个Ring Menu需要有以下基础: 1. 熟练掌握元素的布局与定位; 2. 熟练掌握对元素边框的处理; 3. 熟练掌握伪类:hover的应用; 4. 熟练掌握子选择器的应用; 5. 熟练掌握背景处理; 6. 熟练掌握2D变换; 7. 熟练掌握过渡设置。现在要制作一个 Ring Menu, 效果图如下: 初始状态下: 但鼠标移动到@上时,效果如下:构思: 1.怎么用css实

Python定时任务 Celery+Redis_weixin_30872337的博客-程序员宅基地

引言:  当需要用python创建和完成定时任务时,第一个会想到的就是使用crontab库,  但是crontab不支持Windows系统,于是我们可以使用一个支持Windows且功能强大的库:Celery。Celery-分布式任务队列:  Celery是一个简单,灵活,可靠的分布式系统,用于处理大量消息,同时为操作提供维护此类系统所需的工具。  它是一个任务队列,专注于实时处...

数据库表结构文档自动生成工具_aiyitui0234的博客-程序员宅基地

1.需求描述: 软件开发完成后,交付客户给客户使用前通常需要数据库设计文档,很多程序员甚至项目经理自然会想到采用人海战术,一个项目组的成员,分模块来写,然后合并。作为程序员来说,这种方法是在是太low了。那么能否有自动化工具呢,当然有,用度娘搜索“数据库文档生成器”会出来很多个,他们的质量也会参差不齐,要么格式不满足公司文档格式需要。所以该问题的终极解决方案是理解数据库文档...