最近在等考试结果,闲来无事,干脆开始研究openssl的商密代码编写,在研究途中,偶然发现了一个很有意思的点,于是改编成了一道原创题,希望能加深大家对分组算法的理解。
题目
小P在利用网上下载的工具进行SM4-CTR加密时,发现在输入原文、IV、KEY相同的情况,与通过openssl进行加密的密文不一样,试分析原因。
原文(逗号后面有空格):Hello, SM4!
KEY:0x30313233343536373839616263646566
IV(计数器值):0x30313233343536373839616263646566
工具得到的密文:0x5b42e00fd81c7e6f5e28fabee3f09e83
openssl的密文:0x5b42e00fd81c7e6f5e28fa
分析
1、原文的长度小于SM4的分组长度,所以只有一个分组。
2、openssl的密文和工具的密文前面都是一样的,但工具密文在后面多出来一截,猜测大概率不是加密时出现问题,而是和明文异或时出现问题。
3、CTR模式,在一个分组的情况下,本质就是将计数器值加密,然后和明文异或得到密文,但CTR模式属于流模式,不要求一定达到分组长度整数倍,所以工具的密文之所以多出来一截,是因为原文被填充之后再进行了加密。
解答
知道原因后,我们就可以逆推出明文被填充的数据。
之前提到CTR模式在一个分组的情况下,就是将计数器值加密然后和明文异或。
所以我们直接选择用ECB模式加密计算器值,然后和工具得到的密文异或,就可得到被填充后的明文。
最终我们得到明文为
48656c6c6f2c20534d34210505050505
原来明文是用了PKCS7进行填充后再进行了SM4-CTR加密。
疑问
不过CTR模式的密文到底有没有要求必须达到分组长度的整数倍,这点不敢百分百肯定,欢迎各位大佬留言讨论。