在使用openssl验证自己的程序实现的sm4算法是否正确的时候,遇到加解密与自己程序加解密结果不一致的情况,分析是对openssl的用法有错误。
先展示一下最终正确使用的情况:
KEY:31323334353637383930313233343536(字符串"1234567890123456"的utf8编码)
IV:31323334353637383930313233343536(字符串"1234567890123456"的utf8编码)
明文:31323334353637383930313233343536(字符串"1234567890123456"的utf8编码)
算法:SM4-CBC
填充:PKCS7
使用openssl加密:
[postgres@localhost bin]$ ./openssl sm4-cbc -e -K 31323334353637383930313233343536 -iv 31323334353637383930313233343536 -in test.in -out test.out
[postgres@localhost bin]$ hexdump -C ./test.out
00000000 d2 d6 8e d9 fe 06 cb 40 c9 a1 50 aa 59 17 f1 5f |.......@..P.Y.._|
00000010 e2 65 62 9d 4e 46 1d 14 7c 1d 88 b8 00 c6 ab ba |.eb.NF..|.......|
00000020
[postgres@localhost bin]$
再看在线sm4加密结果:
openssl和在线加密工具加密结果是一致的。
把遇到的问题做一次总结:
1、openssl是以二进制形式读取输入文件test.in(加密内容)的,输入字符串”1234567890123456“到文件test.in,openssl实际读到的是313233343536373839303132333435360a,最后多了一个0a,需要手动去除;
2、通过参数-K和-iv传入的密钥和iv,openssl也是识别为二进制,如果将字符串"1234567890123456"作为密钥,需要如上输入 -K 31323334353637383930313233343536,同理-iv也是这样;
3、openssl默认使用PKCS7进行填充,如果不需要填充可以使用参数-nopad;
4、如果给予的密钥(-K)和IV(-iv)不足16字节,openssl默认使用二进制0进行填充,即如果给予的是31323334353637383930,实际使用的是31323334353637383930313233343536000000000000。