Chinaunix首页 | 论坛 | 博客
  • 博客访问: 15496270
  • 博文数量: 2005
  • 博客积分: 11986
  • 博客等级: 上将
  • 技术积分: 22535
  • 用 户 组: 普通用户
  • 注册时间: 2007-05-17 13:56
文章分类

全部博文(2005)

文章存档

2014年(2)

2013年(2)

2012年(16)

2011年(66)

2010年(368)

2009年(743)

2008年(491)

2007年(317)

分类:

2010-02-27 13:40:51

   加密(签名)的过程是(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 的方式把它们连接起来。
阅读(10593) | 评论(0) | 转发(1) |
给主人留下些什么吧!~~