利用Openssl进行RSA加密签名算法

原创 2005年04月28日 20:34:00

   加密(签名)的过程是(M的e次方)mod n,在这里我们把消息M假定为一个数字,但实际上消息一般为字符串,所以必须有一个将字符串转化为数字的规则,并且要让这个数字的大小和n相当(也不能比n大)。这样做的目的是为了使(M的e次方)> n ,假如不是这样那么C=(M的e次方)mod n = (M的e次方),也就是mod n完全没有作用,攻击者就能够轻松的通过取C的第e次方根来恢复M。那么下面来讨论这种转换的标准:
  1,计算出格式化加密分组所需的大小。如果n是一个L位的数字,那么加密分组就有L/8字节长(只舍不入)。
  2,第一个高位字节总是0,而第二个为分组类型。对加密来说,这是2,对签名来说是1,这样就确保形成的数字比n要稍小。
  3,消息存放在加密分组的低位字节中,并在之前安放一个0
  00 01 ff ff ff ff ...     00 消息数据 —— 这是签名时的转换方式
  00 02 伪随机非零字节 00 消息数据 —— 这是加密时的转换方式
  由这里可以看出,对一个消息进行重复签名时,签名结果是一样的。对一个消息进行反复加密时,得出来的加密分组是不一样的。恢复加密分组时,就只需要从第三个字节开始一直向右推进到一个0字节为止,这就找到了数据起始位置。

但是需要注意上面这个过程中还要加入摘要算法的标识符,因为:
  在RSA_sign函数中在RSA_eay_private_encrypt(i,s,sigret,rsa,RSA_PKCS1_PADDING);函数以前有一段程序,问题的答案就在这里,楼上说的摘要是存在m中的,而s=3020300C06082A864886F70D020505000410+m(34比特),这段程序意思很好理解,就是加上摘要算法的标识符。所以3020300C06082A864886F70D020505000410就是代表md5这个algorithm。
  这样我们就可以得出签名的数据的转化格式
  00 01 ff ff ff ff ... 00 算法标识 消息数据
 
那么我们看看openssl中证书签名的过程:
int X509_sign(X509 *x, EVP_PKEY *pkey, const EVP_MD *md)
{
//先进行ret->cert_info->signature,以及ret->sig_alg的设置;
  inl=i2d_X509_CINF(ret->cert_info,NULL);//求出证书编码后的长度
  buf_in=(unsigned char *)OPENSSL_malloc((unsigned int)inl);//申请空间
  outll=outl=EVP_PKEY_size(pkey1);
  buf_outl=(unsigned char *)OPENSSL_malloc((unsigned int)inl);
  if ((buf_in == NULL) ││ (buf_outl== NULL))
    {
    outl=0;
    goto err;
    }
    p=buf_in;//p与buf-in共享一段地址
    i2d_X509_CINF(ret->cert_info,&p);//将证书编码存入buf-in
    EVP_MD_CTX_init(&ctxl);//初始化
    EVP_SignInit(&ctxl,dgst);//将需要使用的摘要算法存入ctxl中
    EVP_SignUpdate(&ctxl,(unsigned char *)buf_in,inl);//存入证书的编码值
    EVP_DigestFinal(&ctxl,&(m[0]),&m_len);//求取编码的长度为m_len摘要值存入m中
    RSA_sign(ctxl->digest->type,m,m_len,buf_out,outl,pkey->pkey.rsa)//求取摘要值的签名值,最后将长度为outl的签名值存入buf-out。
    RSA_sign最主要是调用了RSA_eay_private_encrypt(int flen, unsigned char *from, unsigned char *to, RSA *rsa, int padding)函数。这里值得注意的一点是: RSA_eay_private_encrypt 加密时默认调用RSA密钥文件中的p、q因子使用中国剩余定理的算法进行加密,这样可以提高效率,而不是直接调用pkey->pkey.rsa->d进行加密,所以有时候直接改动pkey->pkey.rsa->d而加密结果是不会变化的。
  在此过程中编码函数采用了EME-PKCS1——5-ENCOD编码函数,大数与字符串之间的转换函数使用的是OS2IP、I20SP格式转换函数BN_bin2bn和BN_bn2bin。EME-PKCS1_5-ENCODE 函数
输入:字符串 M 、emlen 表示信息编码以后的长度。(注意:信息M 的长度不得大于 emlen-10 个字节)
输出: EM 表示 M 经过编码以后的内容。函数的具体操作步骤是随机产生 emlen-len(M)-2 字节长度的非零字符串PS ,且len(PS)>=8 然后按照下列方式 EM= 02 ││ PS ││ 00 ││ M 的方式把它们连接起来。

OpenSSL 命令详解(二)——摘要算法、签名、验签

本文主要介绍OpenSSL 摘要计算命令。 ref: http://blog.csdn.net/as3luyuan123/article/details/14046375用什么摘要算法指令代替时,...
  • scuyxi
  • scuyxi
  • 2017年02月13日 23:45
  • 3777

调用OpenSSL实现数字签名功能例程(二)

// PKCS7Sign.cpp : Defines the entry point for the console application. // #include "stdafx.h" ...

OpenSSL命令行工具验证数字签名

一、发送方A:生成私钥:OpenSSL> genrsa -passout pass:123456 -out apri.pem 1024生成公钥:OpenSSL> rsa -passin pass:12...

vs2012基于openssl实现对文件中数据的签名与验证

在做这个之前,先要添加openssl的库文件和lib,这个方法参考我的上一篇文章. 3.txt要放到工程目录下 #include #include #include #include ...

openssl中aes、rsa算法的使用

一、RSA 1.  算法原理 2.

RSA算法和RSA数字签名算法的实现

RSA算法和RSA数字签名算法的实现 http://blog.chinaunix.net/uid-21880738-id-1813146.html 顾婷婷 李涛 (四川大学计算机系(西区) ...
  • jiftlixu
  • jiftlixu
  • 2014年02月10日 09:42
  • 10857

Delphi7高级应用开发随书源码

  • 2003年04月30日 00:00
  • 676KB
  • 下载

OpenSSL RSA 消息签名与验证

#include #include #include #include void tSign() { unsigned char sign_value[1024]; //保存签名值的数组 ...

OpenSSL库的RSA使用(下)-rsa函数方式

本文上接:OpenSSL库的RSA使用(上)-EVP方式,URL:http://blog.csdn.net/fenghaibo00/article/details/17248381 3     ...

openssl使用以及C#加密和数字签名

http://blog.csdn.net/scape1989/article/details/18959657
  • sui84
  • sui84
  • 2016年06月29日 18:34
  • 450
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:利用Openssl进行RSA加密签名算法
举报原因:
原因补充:

(最多只允许输入30个字)