免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 4134 | 回复: 9
打印 上一主题 下一主题

(问题解决,谢谢大家)写进去跟读出来的内容不一样了,大家帮我看看 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2011-01-08 18:46 |只看该作者 |倒序浏览
本帖最后由 liukunmeister 于 2011-01-09 16:17 编辑

请大家看看我遇到的最新问题,我在openssl的签名的demo代码中做了一个测试,其实就反应了我现在遇到的问题

#include <stdio.h>
#include <openssl/rsa.h>
#include <openssl/evp.h>
#include <openssl/objects.h>
#include <openssl/x509.h>
#include <openssl/err.h>
#include <openssl/pem.h>
#include <openssl/ssl.h>

int main ()
{
  int err;
  int sig_len;
  unsigned char sig_buf [4096];
  static char certfile[] = "cert.pem";
  static char keyfile[]  = "key.pem";
  static char data[]     = "I owe you...";
  EVP_MD_CTX     md_ctx;
  EVP_PKEY *      pkey;
  FILE *          fp;
  X509 *        x509;

  /* Just load the crypto library error strings,
   * SSL_load_error_strings() loads the crypto AND the SSL ones */
  /* SSL_load_error_strings();*/
  ERR_load_crypto_strings();
  
  /* Read private key */
  
  fp = fopen (keyfile, "r");
  if (fp == NULL) exit (1);
  pkey = PEM_read_PrivateKey(fp, NULL, NULL, NULL);
  fclose (fp);

  if (pkey == NULL) {
        ERR_print_errors_fp (stderr);
        exit (1);
  }
  
  /* Do the signature */
  
  EVP_SignInit   (&md_ctx, EVP_sha1());
  EVP_SignUpdate (&md_ctx, data, strlen(data));
  sig_len = sizeof(sig_buf);
  err = EVP_SignFinal (&md_ctx, sig_buf, &sig_len, pkey);

  if (err != 1) {
        ERR_print_errors_fp(stderr);
        exit (1);
  }

  EVP_PKEY_free (pkey);
注意,问题从这里开始,我把用于保存签名的数组sig_buf以二进制文件操作的形式写到了test_sig文件中,我就按照数组长度4096全写进去了
  fp=fopen("/home/administrator/test_sig","w");
  if(fwrite(sig_buf,sizeof(unsigned char),4096,fp)!=4096)
  {
          printf("fwrite error\n");
          exit(1);
  }
  fclose(fp);
在这里,问题出现了
然而,当我重新定义了一个和sig_buf一样长度的数组,读取同样长度的内容也就是4096, 再往下执行的时候,就会报错,说签名长度有问题.补充一下,如果我还是用sig_buf而不是sigData从test_sig中把保存进去的内容读出来,就又是正确的。

  unsigned char sigData[4096];
  fp=fopen("/home/administrator/test_sig","r");
  if(fread(sigData,sizeof(unsigned char),4096,fp)!=4096)
  {
          printf("fread error\n");
          exit(1);
  }
  fclose(fp);
  
  
  /* Read public key */
  
  fp = fopen (certfile, "r");
  if (fp == NULL) exit (1);
  x509 = PEM_read_X509(fp, NULL, NULL, NULL);
  fclose (fp);

  if (x509 == NULL) {
        ERR_print_errors_fp (stderr);
        exit (1);
  }
  
  /* Get public key - eay */
  pkey=X509_get_pubkey(x509);
  if (pkey == NULL) {
        ERR_print_errors_fp (stderr);
        exit (1);
  }

  /* Verify the signature */
  
  EVP_VerifyInit   (&md_ctx, EVP_sha1());
  EVP_VerifyUpdate (&md_ctx, data, strlen((char*)data));
  err = EVP_VerifyFinal (&md_ctx, sigData, sizeof(sigData), pkey); //这里我也都把以前的sig_buf改为了sigData
  EVP_PKEY_free (pkey);

  if (err != 1) {
        ERR_print_errors_fp (stderr);
        exit (1);
  }
  printf ("Signature Verified Ok.\n");
  return(0);
}
难道签名还记录数组名字?明明一样的数组,sig_buf行,sigData怎么就不行了?

论坛徽章:
324
射手座
日期:2013-08-23 12:04:38射手座
日期:2013-08-23 16:18:12未羊
日期:2013-08-30 14:33:15水瓶座
日期:2013-09-02 16:44:31摩羯座
日期:2013-09-25 09:33:52双子座
日期:2013-09-26 12:21:10金牛座
日期:2013-10-14 09:08:49申猴
日期:2013-10-16 13:09:43子鼠
日期:2013-10-17 23:23:19射手座
日期:2013-10-18 13:00:27金牛座
日期:2013-10-18 15:47:57午马
日期:2013-10-18 21:43:38
2 [报告]
发表于 2011-01-08 19:22 |只看该作者
结果不要当作字符串处理,中间有0的,截断了

论坛徽章:
0
3 [报告]
发表于 2011-01-08 19:31 |只看该作者
结果不要当作字符串处理,中间有0的,截断了
hellioncu 发表于 2011-01-08 19:22


不当字符串处理,我怎么来处理呢?

论坛徽章:
324
射手座
日期:2013-08-23 12:04:38射手座
日期:2013-08-23 16:18:12未羊
日期:2013-08-30 14:33:15水瓶座
日期:2013-09-02 16:44:31摩羯座
日期:2013-09-25 09:33:52双子座
日期:2013-09-26 12:21:10金牛座
日期:2013-10-14 09:08:49申猴
日期:2013-10-16 13:09:43子鼠
日期:2013-10-17 23:23:19射手座
日期:2013-10-18 13:00:27金牛座
日期:2013-10-18 15:47:57午马
日期:2013-10-18 21:43:38
4 [报告]
发表于 2011-01-08 20:20 |只看该作者
不用fgets,strcat,用fread,memcpy之类的

论坛徽章:
0
5 [报告]
发表于 2011-01-08 20:49 |只看该作者
不用fgets,strcat,用fread,memcpy之类的
hellioncu 发表于 2011-01-08 20:20


关键是我也不知道这个签名有多长,我很好奇,如果openssl的库函数不是通过'\0'空字符来判断结尾的,那它是怎么来判断这个签名长度的?

论坛徽章:
324
射手座
日期:2013-08-23 12:04:38射手座
日期:2013-08-23 16:18:12未羊
日期:2013-08-30 14:33:15水瓶座
日期:2013-09-02 16:44:31摩羯座
日期:2013-09-25 09:33:52双子座
日期:2013-09-26 12:21:10金牛座
日期:2013-10-14 09:08:49申猴
日期:2013-10-16 13:09:43子鼠
日期:2013-10-17 23:23:19射手座
日期:2013-10-18 13:00:27金牛座
日期:2013-10-18 15:47:57午马
日期:2013-10-18 21:43:38
6 [报告]
发表于 2011-01-08 20:59 |只看该作者
关键是我也不知道这个签名有多长,我很好奇,如果openssl的库函数不是通过'\0'空字符来判断结尾的,那它 ...
liukunmeister 发表于 2011-01-08 20:49



    签名结果是定长的,算法决定

论坛徽章:
0
7 [报告]
发表于 2011-01-08 23:44 |只看该作者
RSA_sign,RSA_public_encrypt, RSA_private_encrypt之类的东西不是会返回签名长度么,仔细看看manual呢?虽然它的文档确实很糟糕……

论坛徽章:
0
8 [报告]
发表于 2011-01-09 02:32 |只看该作者
openssl有簽名的例子 另外網上也有簽名的例程 另外使用最新版的openssl 該釋放的都要釋放 否則可能引起 內存洩露問題

论坛徽章:
0
9 [报告]
发表于 2011-01-09 08:53 |只看该作者

  1. #include <stdio.h>
  2. #include <openssl/rsa.h>
  3. #include <openssl/evp.h>
  4. #include <openssl/objects.h>
  5. #include <openssl/x509.h>
  6. #include <openssl/err.h>
  7. #include <openssl/pem.h>
  8. #include <openssl/ssl.h>

  9. int main ()
  10. {
  11.   int err;
  12.   int sig_len;
  13.   unsigned char sig_buf [4096];
  14.   static char certfile[] = "cert.pem";
  15.   static char keyfile[]  = "key.pem";
  16.   static char data[]     = "I owe you...";
  17.   EVP_MD_CTX     md_ctx;
  18.   EVP_PKEY *      pkey;
  19.   FILE *          fp;
  20.   X509 *        x509;
  21.   int i;

  22.   /* Just load the crypto library error strings,
  23.    * SSL_load_error_strings() loads the crypto AND the SSL ones */
  24.   /* SSL_load_error_strings();*/
  25.   ERR_load_crypto_strings();
  26.   
  27.   /* Read private key */
  28.   
  29.   fp = fopen (keyfile, "r");
  30.   if (fp == NULL) exit (1);
  31.   pkey = PEM_read_PrivateKey(fp, NULL, NULL, NULL);
  32.   fclose (fp);

  33.   if (pkey == NULL) {
  34.         ERR_print_errors_fp (stderr);
  35.         exit (1);
  36.   }
  37.   
  38.   /* Do the signature */

  39.   memset(sig_buf,0,sizeof(sig_buf));



  40.   //EVP_SignInit   (&md_ctx, EVP_sha1());
  41.   EVP_SignInit   (&md_ctx, EVP_sha256());
  42.   EVP_SignUpdate (&md_ctx, data, strlen(data));
  43.   sig_len = sizeof(sig_buf);
  44.   err = EVP_SignFinal (&md_ctx, sig_buf, &sig_len, pkey);

  45.   if (err != 1) {
  46.         ERR_print_errors_fp(stderr);
  47.         exit (1);
  48.   }

  49.   EVP_PKEY_free (pkey);

  50.   for(i=0;i< sig_len;i++)
  51.         printf("%02X",sig_buf[i]);

  52.   
  53.   /* Read public key */
  54.   
  55.   fp = fopen (certfile, "r");
  56.   if (fp == NULL) exit (1);
  57.   x509 = PEM_read_X509(fp, NULL, NULL, NULL);
  58.   fclose (fp);

  59.   if (x509 == NULL) {
  60.         ERR_print_errors_fp (stderr);
  61.         exit (1);
  62.   }
  63.   
  64.   /* Get public key - eay */
  65.   pkey=X509_get_pubkey(x509);
  66.   if (pkey == NULL) {
  67.         ERR_print_errors_fp (stderr);
  68.         exit (1);
  69.   }

  70.   /* Verify the signature */
  71.   
  72.   //EVP_VerifyInit   (&md_ctx, EVP_sha1());
  73.   EVP_VerifyInit   (&md_ctx, EVP_sha256());
  74.   EVP_VerifyUpdate (&md_ctx, data, strlen((char*)data));
  75.   err = EVP_VerifyFinal (&md_ctx, sig_buf, sig_len, pkey);
  76.   EVP_PKEY_free (pkey);

  77.   if (err != 1) {
  78.         ERR_print_errors_fp (stderr);
  79.         exit (1);
  80.   }
  81.   printf ("\nSignature Verified Ok.\n");
  82.   return(0);
  83. }
复制代码

论坛徽章:
0
10 [报告]
发表于 2011-01-09 10:49 |只看该作者
wenlq 发表于 2011-01-09 08:53


我其实用的就是这个例子,但是它是直接用库函数,拿数组就验证了,但是我要把数组里的签名写到文件里保存,然后再从文件读出来验证,其实就是把这个程序分成了两部分,一部分签名,一部分验证,中间加上读写文件操作,而也恰恰就是读写文件操作出问题了。。。。。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP