密码引擎-商用密码算法实现2-交叉测试
1.实验前提
使用的参考代码:https://github.com/NEWPLAN/SMx
2.实验内容
2.1 自己实现的SM3算法的结果与OpenSSL的结果比对是否一致
- 首先可以看到在自己实现的SM3算法,zyj的摘要如下:
- 在OpenSSL下,摘要值:
发现结果并不一样,其实是要用-m32 生成32位机器的汇编代码;
- 输入指令
gcc -m32 *.c -o sm3.exe
直接输入会报错:/usr/include/stdio.h:26:10: fatal error: bits/libc-header-start.h: 没有那个文件或目录编译中断
主要是gcc安装环境没有安装完善
- 输入指令
sudo apt-get install gcc-multilib
再次编译运行即可
- 再检验一下abcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcd
也是一样的。
2.2 自己实现的SM4算法加密的,OpenSSL的SM4算法解密,或者相反
- 首先可以看到在自己实现的SM4算法,原文密钥和加密后如下:
2.2.1 重现加密
我打算先用openssl重现一下SM4加密,看看结果是否一样,我这边加密的原文和密钥均为0123456789abcdeffedcba9876543210
- 将原文改成十六进制文件再进行操作,我使用的是VSCode的HexEditor插件
- 输入命令(zyj.txt就是我的0123456789abcdeffedcba9876543210的十六进制文件。)
openssl enc -sm4-ecb -in zyj.txt -K 0123456789abcdeffedcba9876543210 -out zyj2.txt
注意这里为-sm4-ecb,之前做过别的尝试,均不对且报错IV,IV加上也不对,查看使用的代码发现并没有用IV,所以推测为ECB加密
- 查看zyj2.txt
可以看到与代码的加密结果相同,但是多了一行,分析后认为是文件结束符也被加密了,苦于不知道加密的填充方式究竟是哪一种,无从验证多的一行。
- 所以在指令中再加入参数 -nopad 不使用补齐
openssl enc -sm4-ecb -in zyj.txt -nopad -K 0123456789abcdeffedcba9876543210 -out zyj2.txt
- 查看生成的zyj3.txt
成功了!
2.2.2 使用OpenSSL解密SM4中加密的内容
可以将代码生成的加密后的文件,我这里使用的是刚刚加密后的文件,都是相同的
- 输入指令
openssl enc -d -sm4-ecb -in zyj3.txt -nopad -K 0123456789abcdeffedcba9876543210 -out zyjd.txt
- 查看生成的zyjd.txt
解密成功!
2.3 自己实现的SM2算法签名,OpenSSL的SM2算法验签,或者相反
3. 出现的其他错误及解决办法
3.1 引用openssl静态库libcrypto.a和libssl.a出现undefined reference to错误的问题
/usr/bin/ld: /usr/local/lib/libcrypto.a(dso_dlfcn.o): in function `dlfcn_unload': dso_dlfcn.c:(.text+0x6b8): undefined reference to `dlclose' collect2: error: ld returned 1 exit status
其实是引用openssl静态库libcrypto.a和libssl.a出现undefined reference to错误的问题
在链接这个库的时候一定要注意2个问题:
- openssl库的版本问题,请直接链到你需要的openssl库路径,比如我的就是/usr/local/openssl/lib,
- 注意-lssl -lcrypto要写在-ldl -lpthread前面,这四个必须要。
仔细看错误原因,位置在CMakeFiles/sm2.dir/build位置底下
是在我们make的时候有个文件叫做link.txt,就是链接库的文件,在文件的-lssl -lcrypto后加上-ldl -lpthread,再make就🆗了。