当前位置: 首页 > 知识库问答 >
问题:

用C语言中的AES-256和openssl计算CBC-MAC

秦宁
2023-03-14

我想用开放计算给定明文的CBC-MAC。我有以下明文(十六进制转储):

hexdump -C example.txt
00000000  4d 41 43 73 20 61 72 65  20 76 65 72 79 20 75 73  |MACs are very us|
00000010  65 66 75 6c 20 69 6e 20  63 72 79 70 74 6f 67 72  |eful in cryptogr|
00000020  61 70 68 79 21 20 20 20  20 20 20 20 20 20 20 20  |aphy!           |

如果我使用openssl的命令行功能,我会得到以下解决方案:

openssl aes-256-cbc -in example.txt -K 8000000000000000000000000000000000000000000000000000000000000001 -e -iv 00 | hexdump -C
00000000  e8 e9 a4 ce 5d 20 c4 ad  f5 52 b2 c6 38 2e 12 4e  |....] ...R..8..N|
00000010  20 f5 63 65 b4 b3 96 9f  ad 8d ca e4 e8 34 2a e5  | .ce.........4*.|
00000020  0d 82 0e 3a 1e 10 5d 30  72 16 fc 00 c7 a5 b4 49  |...:..]0r......I|
00000030  f5 63 9f 85 ff e3 a4 a4  23 6e 6f 09 20 ed b1 ae  |.c......#no. ...|

目前为止,一切都好。我有一个额外的块,因为第一个块应该是加密的IV。现在最后一行应该是我的CBC-MAC,如果我理解正确的话。接下来,我试图在C中做同样的事情,下面是示例代码:

#include <stdio.h>
#include <string.h>
#include <openssl/sha.h>
#include <openssl/aes.h>

int main(int argc, char *argv[])
{
    unsigned char obuf[64] = {0};
    unsigned char decbuf[48] = {0};
    unsigned char msg1[] = {0x4d, 0x41, 0x43, 0x73, 0x20, 0x61, 0x72, 0x65, 0x20, 0x76, 0x65, 0x72, 0x79, 0x20, 0x75, 0x73,
                            0x65, 0x66, 0x75, 0x6c, 0x20, 0x69, 0x6e, 0x20, 0x63, 0x72, 0x79, 0x70, 0x74, 0x6f, 0x67, 0x72, 
                            0x61, 0x70, 0x68, 0x79, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20};
    unsigned char key[] =  {0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
                            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01};
    unsigned char ivenc[] ={0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
    unsigned char ivdec[] ={0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
    int i=0;

    AES_KEY enc_key, dec_key;
    AES_set_encrypt_key(key, 256, &enc_key);
    AES_cbc_encrypt(msg1, obuf, 48, &enc_key, ivenc, AES_ENCRYPT);

    for (i = 0; i < 64; i++) {
        if (!(i%16))
            printf("\n");
        printf("%02x ", obuf[i]);
    }
    printf("\n");

    AES_set_decrypt_key(key, 256, &dec_key);
    AES_cbc_encrypt(obuf, decbuf, 64, &dec_key, ivdec, AES_DECRYPT);

    for (i = 0; i < 48; i++) {
        if (!(i%16))
            printf("\n");
        printf("%02x ", decbuf[i]);
    }
    printf("\n");

    return 0;
}

之后,我解密加密的消息以验证我的代码。我的代码输出非常令人惊讶:

e8 e9 a4 ce 5d 20 c4 ad f5 52 b2 c6 38 2e 12 4e 
20 f5 63 65 b4 b3 96 9f ad 8d ca e4 e8 34 2a e5 
0d 82 0e 3a 1e 10 5d 30 72 16 fc 00 c7 a5 b4 49 
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 

4d 41 43 73 20 61 72 65 20 76 65 72 79 20 75 73 
65 66 75 6c 20 69 6e 20 63 72 79 70 74 6f 67 72 
61 70 68 79 21 20 20 20 20 20 20 20 20 20 20 20 

加密的消息与命令行输出完全相同,只是最后一行全部为 0。我想,第一行是加密的IV,接下来的三行是加密的消息,所以根据我的解释,消息的最后一行没有加密。但令我惊讶的是,解密结果正好是我用作输入的文本,因此似乎没有丢失信息。

问题:

    < li >即使我没有最后一行,我怎么可能解密我的加密输出? < li >什么是我的CBC-MAC?是我命令行输出的最后一行还是我C代码输出的最后一行? < li >我在C代码中做错了什么吗?我用这个so问题作为帮助。

共有1个答案

沈旻
2023-03-14

你的错误在这里:

我有一个额外的块,因为第一个块应该是加密的IV。

额外的块是因为OpenSSL向纯文本添加了填充,所以它是块大小的倍数(对于AES是16字节)。在这种情况下,纯文本已经是16字节的倍数,但是所使用的填充方案(PKCS7)总是添加填充,所以这里在加密之前添加整个块。

在密文的前面添加IV是很常见的,但这不是这里发生的事情。

为了从代码中获得相同的结果,您需要自己添加此填充。在这种情况下,它相当简单,只需在 msg1 的末尾添加 16 0x10 字节(因此其 toal 长度为 64),然后将调用中的 48 更改为 AES_cbc_encrypt64。您看到的零只是您初始化 obuf 的值,因为您只向此缓冲区写入 48 个字节。

 类似资料:
  • 我是密码学的新手。我的要求是对使用openssl加密/解密的文本进行解密/加密。我们在Openssl中使用的算法是aes-256-cbc。因此,我尝试在我的应用程序中实现相同的功能。到目前为止,在谷歌搜索了很多次之后,我所能做的就是。。 我的openssl命令是 我的密钥长度是32位IV是16位 Thnx...

  • 我希望有一个用C编写的程序,可以在没有openssl这样的大型库的帮助下,用AES-CBC对字符串进行编码/解码。 目标: 使用密码短语对字符串进行编码/解码: 因此,应用程序需要接受3个输入参数。。。 输入字符串(待编码)/或已编码字符串(待解码) 用于编码/解码字符串的密码 编码或解码指示器 我对C语言不熟悉(我可以用C#编码)。 我已经找到了https://github.com/kokke/

  • 我只想用这3种模式测试openSSL中的AES:128192和256密钥长度,但我解密的文本与我的输入不同,我不知道为什么。此外,当我传递一个巨大的输入长度(比如1024字节)时,我的程序显示。。。我的意见总是一样的,但这并不重要,至少现在是这样。代码如下: 编辑: 当我将输出大小更改为而不是时,我得到了结果: 那么,是否有可能存在Outpus大小和IV大小的问题?它们应该有什么尺寸(AES-CB

  • 我想做的是:用C编写一个程序,打开任意大小的文件并读取其内容。一旦内容被读取,它将在AES 256 CBC中对其进行加密,并将密文保存到名为ciphertext的文件中。保存后,它将关闭两个文件。然后将打开刚刚保存的文件中的密码文本,解密密码文本并将其保存到名为decrypted的文件中。 我的问题是:它似乎永远不会解密我的密文。我收到垃圾,我不知道我做错了什么。请帮忙。 注意:可能有一些拼写错误

  • 注意,这只提供salt和密码,openssl应该自动处理key和IV。我是不是太乐观了,当浏览器解密时也会发生这种情况?如果可能的话,我希望只使用那些加密设置,或者增加的复杂性最小。在浏览器中,我正在尝试使用CryptoJS解密,如下所示: 但使用的属性“0”,。cryptojs.aes.decrypt的文档很薄,我知道在调用该函数时要更改的任何设置似乎都会给出相同的错误。感谢任何一个能发光的人!

  • 我使用以下命令加密了一个文件 openssl rand 32>test.key openssl enc-aes-256-cbc-iter 10000-pbkdf2-salt-输入test.txt-输出test.txt.enc-通过文件:test.key 我的代码 我得到的错误 我引用了以下链接 尝试使用时,仍然得到错误