免费注册 查看新帖 |

Chinaunix

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

[C++] 急!!!!C++编程中遇到一个非常奇怪的问题,希望大家能帮忙解决以下!! [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2015-07-21 14:46 |只看该作者 |倒序浏览
本帖最后由 sandaojushi 于 2015-07-21 14:51 编辑

大家好,最近在写一个程序的时候遇到了非常非常奇怪的问题,花了好几天时间仍然无法解决,问题描述如下:
这个程序是对数据进行加密的一个程序,用的加密算法是sm4加密算法,我的程序代码如下:
  1. void block_encrypt(const void *ptext,void *ctext) {
  2.              sm4_setkey_enc(&ctx,(unsigned char *)smkey);
  3.              sm4_crypt_ecb(&ctx,1,16,(unsigned char*)ptext,(unsigned char*)ctext);
  4.      }
  5.      void block_decrypt(const void *ctext,void *ptext) {
  6.              sm4_setkey_dec(&ctx,(unsigned char *)smkey);
  7.              sm4_crypt_ecb(&ctx,0,16,(unsigned char*)ctext,(unsigned char*)ptext);
  8.      }
复制代码
上面是加密解密的第一层封装
  1. uint64_t encrypt(uint64_t pt)
  2.     {
  3.        uint64_t ct;
  4.        block_encrypt(&pt,&ct);
  5.        return ct;
  6.     }
  7.       uint64_t decrypt(uint64_t ct)
  8.      {
  9.         uint64_t pt;
  10.         block_decrypt(&ct,&pt);
  11.         return pt;
  12.      }
复制代码
这是二次封装

然后我在主程序中调用下面的二次封装接口
   uint64_t ctext;
   ctext=bf.encrypt(ptext);
直接这样调用后在encrypt函数中返回ct的时候就出现cannot access memory xxxx 错误(encrypt和decrypt函数都存在这样的问题).
奇怪的是,我把encrypt和decrypt函数做以下修改后:
  1. uint64_t encrypt(uint64_t pt)
  2.     {
  3.        uint64_t ct;
  4.        block_encrypt(&pt,&ct);
  5.        uint64_t tc=ct
  6.        return tc;
  7.     }
  8.       uint64_t decrypt(uint64_t ct)
  9.      {
  10.         uint64_t pt;
  11.         block_decrypt(&ct,&pt);
  12.         uint64_t tp=pt;
  13.         return tp;
  14.      }
复制代码
程序就正常了.
本以为就此可以解决,然后在进一步测试发现,如果我在加密后,用一个密文ctext和一个明文ptext变量直接调用block_decrypt函数,就能正确解密.
就像这样:
  1. uint64_t ptext;
  2.         uint64_t ctext;
  3.            bf.block_encrypt(&ptext,&ctext);
  4.         bf.block_decrypt(&ctext,&ptext);
复制代码
此时的ptext函数就可以正常得到解密的数据,然而如果我调用decrypt接口,就会出错,其实decrypt就是做了一个值传递的操作,但是解密结果会变得乱七八糟.
然后我根据上面的判断尝试这么做来测试:
   ctext是密文,我再新建一个变量.
   uint64_t tempctext=ctext;
   然后bf.block_decrypt(&tempctext,&ptext);
   这个时候就无法正确解密了.
   也就是说对于密文来说,我只能存放在那个我原来的变量里才能加解密,如果传递给另外的变量,加解密就出错了.
   实在不知道为何,请大家帮帮忙吧!
  这里是我写的一个测试程序!!
    sm4test.tar.gz (10.88 KB, 下载次数: 5)

论坛徽章:
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 [报告]
发表于 2015-07-21 14:58 |只看该作者
sm4_crypt_ecb要求16字节吧,你int64_t只有8字节,越界了

论坛徽章:
0
3 [报告]
发表于 2015-07-21 15:19 |只看该作者
这个问题我也想到了,我就用了一个union来扩展我这个uint64_t,但是结果还是错的。回复 2# hellioncu


   

论坛徽章:
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 [报告]
发表于 2015-07-21 15:22 |只看该作者
sandaojushi 发表于 2015-07-21 15:19
这个问题我也想到了,我就用了一个union来扩展我这个uint64_t,但是结果还是错的。回复 2# hellioncu


...


没看到哪里有union

论坛徽章:
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
5 [报告]
发表于 2015-07-21 15:23 |只看该作者
代码直接贴出来,很少有人愿意为了帮别人解决问题去下载、解压

论坛徽章:
0
6 [报告]
发表于 2015-07-21 15:33 |只看该作者
回复 5# hellioncu
  1. #define CLEAR(x) memset(&(x), 0, sizeof(x))
  2. typedef union _Data
  3. {
  4.                 uint64_t digital;
  5.                 char data[16];
  6. }Data;

  7. Data input, output;
  8.    CLEAR(input);
  9.    CLEAR(output);
  10. input.digital=123456789;
  11. //这样是可以的
  12. bf.block_encrypt(input.data,output.data);
  13. bf.block_decrypt(output.data,input.data);
  14. //这样就不行了
  15. Data input_test;
  16. CLEAR(input_test);
  17. input_test.digital=input.digital;
  18. bf.block_decrypt(output.data,input_test.data);
复制代码
我的做法是首先新建一个联合体16字节,然后清空联合体,再把前8个字节赋值,再传入进去,但是这么做依然会出错.不知为何...

论坛徽章:
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
7 [报告]
发表于 2015-07-21 15:40 |只看该作者
sandaojushi 发表于 2015-07-21 15:33
回复 5# hellioncu 我的做法是首先新建一个联合体16字节,然后清空联合体,再把前8个字节赋值,再传入进去,但是 ...


你要把input整体16字节复制到input_test才行,而不是仅仅复制digital这8字节。

这算法以每块16字节作为加解密最小单位的

论坛徽章:
0
8 [报告]
发表于 2015-07-21 15:46 |只看该作者
回复 7# hellioncu
非常感谢,我马上来尝试一下!!
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP