跳到主要内容

AES CBC没有填充

1 year ago

AES CBC没有填充

张贴了托马斯唐豪瑟0分 5回复
0 upvotes

你好PM_dialog!

我使用此代码在我的应用程序中加密数据:

hw_aes_hash_setup s;Memset(&s,0,sizeof(hw_aes_hash_setup));UINT8 AESKEY [32] = {1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,};char p [] =“SiC Transit Gloria Mundi-123456。”;char e [128];Memset(E,0,Sizeof(e));s.mode = hw_aes_cbc;s.aesdirection = hw_aes_encrypt;s.aeskeysize = hw_aes_256;s.aeskeyexpand = hw_aes_do_not_perform_key_expansion; s.aesKeys = (uint32)&aesKey; s.aesIvCtrblk_0_31 = 0x01020304; s.aesIvCtrblk_32_63 = 0x05060708; s.aesIvCtrblk_64_95 = 0x090A0B0C; s.aesIvCtrblk_96_127 = 0x0D0E0FA1; s.aesWriteBackAll = true; s.moreDataToCome = false; s.sourceAddress = (uint32)&p; s.destinationAddress = (uint32)&e; s.dataSize = 32; s.enableInterrupt = false; s.callback = 0; hw_aes_hash_init(&s); hw_aes_hash_start(); while(hw_aes_hash_is_active()){}; hw_aes_hash_disable_clock();

As I'v read in relevante documents the length in e[128] should be 48 byte in this case . Because of the plain-text length is 32 + padding based on AES CBC. But in fact the encrypted result in e[128] is only 32 byte long after processing it.

The counterpart of this app is an iOS and Android app. The ecryption shows the same result for the first 32 byte - as expectet. But iOS and Android are adding padding data to the result like and it looks like this:

26 9D F3 2B 94 E9 CD DE 7A D2 6F E8 7A 7E 8D A8 1F E1 CA B7 BF A7 4F C7 17 F3 D4 2F BB E6 C3 C7 39 7A 92 FE 54 98 C7 F8 2F 13 93 15 3A 43 B0 3E

DA14683上的加密结果:

26日9 d f3 2 b 94 e9 cd de 7 d2 6 f e8 7 7 e8d a8 1f e1 ca b7 bf a7 4f c7 17 f3 d4 2f bb e6 c3 c7

所以请你解释如何获得相同的结果或其他行为。

谢谢!
Thomas

1 year ago

PM_Dialog

托马斯,

使用SDK1.0.14和DA14683,我在我的侧面上了您附加的代码。请在下面找到我的评论:

1. The size of the output vector (e[]) will be equal with the size of the input vector (p[]). To do so, if you would like to have 128 bytes in the output, you should adjust the input accordingly.

2. The s.dataSize item is set to 32. The data size should be dynamically configured according to the input size. My recommendation would be to change it like below:

s.datasize = sizeof(p);

3. In your provided code snippet, the key expansion is performed by thesoftware,

s.aeskeyexpand = hw_aes_do_not_perform_key_expansion;

这是一种错误的方法,如根据数据表,关键 - 扩展是基于初始密钥生成密钥数的过程。更多特定于分别从128,192和256比特的初始键生成11,13和15键。每轮算法都使用上述键中的每一个。对于每128位输入的加密,我们需要从此过程中使用所有生成的键。

这意味着如果将其设置为发动机执行,则软件将读取32位的15个AES键。请检查hw_aes_hash_store_keys()的源代码。

我强烈建议您更改发动机执行的关键扩展,如下所示:

s.aeskeyexpand = hw_aes_perform_key_expansion;

Key expansion will be performed by the dedicated hardware engine. Otherwise key expansion should be performed by software and generated keys should be stored into CRYPTO_KEYS memory.

4. s.moreDataToCome = false; : as according to Table 32: Restrictions on CRYPTO_LEN of the DA14683 datasheet, when CRYPTO_LEN CRYPTO_MORE_IN = 0, in AES CBC mode there are no restriction, If you change it to “true”, it should be multiple of 16.

Thanks, PM_Dialog

1 year ago

托马斯唐豪瑟 0分

你好PM_DIALOG!

当你想要我这样做时,我跟随你的建议并改变了片段。当我弄错时,它应该如下所示:

hw_aes_hash_setup s;Memset(&s,0,sizeof(hw_aes_hash_setup));UINT8 AESKEY [32] = {1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,};char p [] =“SiC Transit Gloria Mundi-123456。”;char e [128];char d[128]; memset(e,0,sizeof(e)); memset(d,0,sizeof(e)); s.mode = HW_AES_CBC; s.aesDirection = HW_AES_ENCRYPT; s.aesKeySize = HW_AES_256; s.aesKeyExpand = HW_AES_PERFORM_KEY_EXPANSION; s.aesKeys = (uint32)&aesKey; s.aesIvCtrblk_0_31 = 0x01020304; s.aesIvCtrblk_32_63 = 0x05060708; s.aesIvCtrblk_64_95 = 0x090A0B0C; s.aesIvCtrblk_96_127 = 0x0D0E0FA1; s.aesWriteBackAll = true; s.moreDataToCome = true; //false; s.sourceAddress = (uint32)&p; s.destinationAddress = (uint32)&e; s.dataSize = sizeof(p); s.enableInterrupt = false; s.callback = 0; hw_aes_hash_init(&s); hw_aes_hash_start(); while(hw_aes_hash_is_active()){}; hw_aes_hash_disable_clock();

这最终陷入了HW_AES_HASH_INIT()的崩溃。所以我强烈怀疑你的建议在你身边。你能发布你拍摄的代码吗?

我可能解释过不够清楚的问题是什么。通常AES-CBC加密需要在最后使用0x10填充。那里的计算是:

sizeof(p) + (16 - (sizeof(p) % 16));

In case of the message "Sic transit gloria mundi-123456." the calculation gives 48. Even is the message has a lenght of 32 char the calculated encryption lenght is also 48. I'v testet the message on thehttps://crypti.com/pipes/aes-encryption.as well as on iOS and Android and in all three platform I'll get the same encrypted result. Only the da14683 does not extend the encrypted results with a proper padding. As far as I understood PKCS#7 padding is mandatory for AES-CBC encryption.

所以我再次知道如何参数化hw_aes_hash_setup以获得与其他平台上的类似结果。

谢谢你的尊重,

Thomas

1 year ago

PM_Dialog

托马斯,

The following code snippet is used in the freertos_retarget example of the SDK.

Import the following library:

#include“hw_aes_hash.h”

在for(;)循环之前的main()中调用以下代码。输入载体增加了一倍,因此我的输出双倍增加。

hw_aes_hash_setup s;Memset(&s,0,sizeof(hw_aes_hash_setup));UINT8 AESKEY [32] = {1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,};char p[] = "Sic transit gloria mundi-123456.Sic transit gloria mundi-123456."; char e[128]; memset(e,0,sizeof(e)); s.mode = HW_AES_CBC; s.aesDirection = HW_AES_ENCRYPT; s.aesKeySize = HW_AES_256; s.aesKeyExpand = HW_AES_PERFORM_KEY_EXPANSION; s.aesKeys = (uint32)&aesKey; s.aesIvCtrblk_0_31 = 0x01020304; s.aesIvCtrblk_32_63 = 0x05060708; s.aesIvCtrblk_64_95 = 0x090A0B0C; s.aesIvCtrblk_96_127 = 0x0D0E0FA1; s.aesWriteBackAll = true; s.moreDataToCome = false; s.sourceAddress = (uint32)&p; s.destinationAddress = (uint32)&e; s.dataSize = sizeof(p); s.enableInterrupt = false; s.callback = 0; hw_aes_hash_init(&s); hw_aes_hash_start(); while(hw_aes_hash_is_active()){}; hw_aes_hash_disable_clock();

你可以在你身边测试它并分享结果吗?

Thanks, PM_Dialog

1 year ago

托马斯唐豪瑟 0分

你好,

它已经花了一些时间,但现在我完成了它,结果是:

b86fd2d7de80d4e7cb626ca6e75343695066e13445430c9fbbb8dcccf8df0e34
A33003F124E39ED42B53E200502C4A251E936B50BCB71261C1AD1E06735ABE4F.
03

The encrpyted result is 65 byte long because in input-data are also 65 byte in length (string + terminating 0).

所以结论是AES-CBC加密不支持PKCS#7填充。AES-CBC模式的加密是在任何平台(IOS,Android ...)上完成PKCS#7填充的平台。从我的角度来看,这是错误的实现。或许我只是不知道如何配置它。可能你们甚至不知道。:-)

问候,
Thomas

接受答案!

1 year ago

bobspam@free.fr. 50分

你好

You are right PKCS7 is not implemented on DA1468x platform. If you want to have AES-CBC data to be compliant with openssl, you will have to implement it by hand.

查看我以前的帖子:

https://support.dialog-semiconductor.com/forums/post/dialog-smartbond-b…

以下是我编写的实现,以使用OPenSSL使用AES-CBC-256解码的数据

uint32_t * const size_out;

uint32_t size_in;

uint32_t padding_size;
uint8_t i;

//添加填充
* size_out =(((size_in - 1)/ 16)+ 1)* 16;
padding_size = *size_out - size_in;
for(i = 0; i data_in[size_in + i] = padding_size;
}
size_in + = padding_size;

You have to achieve this before ciphering. This is the reason why I am working on input_data.

我还发现openssl意味着填充的块的最后一个字节始终使用。这意味着您不能再使用块的大小或需要添加额外块的有效载荷Mathcing,以便您始终具有传输的填充数据。这就是为什么OpenSSL / Android / iPhone加密消息长于DA。

希望能帮助到你

此致

Simon