【问题标题】:AES ECB known-text attackAES ECB 已知文本攻击
【发布时间】:2018-08-08 08:45:25
【问题描述】:

我正在尝试执行已知文本攻击以获取 32 字节密钥。 BlockSize 为 16 字节。

对此:https://crypto.stackexchange.com/a/12512

或者这个:https://security.stackexchange.com/a/102110

据我所知:

1) 加密已知的 15 字节块

2) 用不同的尾字节加密已知的 256 个 16 字节块

3) 比较块并得到一个字节的秘密

void test() {
    unsigned char KnownText[15];
    memset(KnownText, 'A', 15);

    unsigned char EncryptedText[32];
    int result_size = AES_ECB.EncryptBlock(EncryptedText, KnownText, 15);

    unsigned char CKnownText[16];
    for (int i = 0; i < 256; ++i) {
        memset(CKnownText, 'A', 16);
        CKnownText[15] = i;

        unsigned char Encrypted[32];
        int enc_result = AES_ECB.EncryptBlock(Encrypted, CKnownText, 16);

        if(memcmp(EncryptedText, Encrypted, 16) == 0) {
            //match found
        }
    }
}

当 i=0 时,我只得到一个匹配项(假设因为 0 被附加到第一个 15 字节块),它甚至不是任何密钥字节。

我可以加密任何长度的任何已知数据并获得加密结果。

我怎样才能通过这种攻击获得密钥?

【问题讨论】:

  • 如果这是 C,BYTE 是什么?更传统的表示法是unsigned charuint8_t。这是 AES 库强加的类型吗?这是 C++ 代码吗?
  • BYTEunsigned char。我已经删除了 c++ 标签,因为有人评论说它更像是 c 代码。在这种情况下,c++ 或 c 并不重要。无论如何,我已经将代码编辑得更清楚了。
  • 如果你正在做类似AES_ECB.EncryptBlock(...) 的事情,这真的不是C 的事情。此外,在使用 C++ 时,您可以使用 std::stringstd::vector 等工具,而不是 C 样式的字节数组(如果相关)。
  • 如果我像AES_ECB_EncryptBlock(...) 那样做某事,它可能是 C,毕竟它只是一个处理块的函数。
  • "...如何使用此攻击获取密钥?":该链接是关于查找预先附加的密钥 (salt) 而不是加密密钥。引用:“如果服务器将我控制的数据附加到一个秘密......我有可能弄清楚秘密是什么......”

标签: c++ algorithm encryption aes


【解决方案1】:

EncryptBlock 可能会像它所说的那样做:加密一个块。 15 字节第一条消息的想法是,然后您将密钥块连接到它。我看不出这是在哪里发生的(除非 EncryptBlock 的名字非常糟糕)。

目前,EncryptBlock 函数可能将加密的第 16 个字节简单地设置为零(使用零填充)。您可能需要创建一个函数来模拟服务器应该做的事情,包括将服务器的秘密添加到初始消息中并可能处理加密多个块(假设该函数尚未这样做)。

请注意,这不是从分组密码中检索密钥,而是从明文中检索秘密。这个秘密可能是作为执行消息身份验证的恶意尝试而添加的。

【讨论】:

  • 似乎 EncryptBlock 的名字很糟糕,它对大小的字节数组进行了块加密。因此,如果我传递大小 32 或 48,它将相应地生成 Size+(BlockSize-Size%BlockSize)+1 2 或 3 个加密块的加密字节数组。这不是某种服务器-客户端加密。普通的 c++ 项目。我确信我需要 2 或 3 个已知文本块来获取密钥,因为它写在每份 ECB 攻击文件中。但我坚持尝试完成第一步 - 正如这些指南所说,获取密钥的第一个字节。顺便说一句,我尝试加密 3 块数组。它产生预期的结果 3 个相同的块。
  • 抱歉,但在这种情况下,它只执行零填充的 ECB 模式加密。因此它将能够处理多个块,这不是您对函数名称的期望。但是仍然没有添加包含秘密的两个块的部分,并且该方法显然也没有添加两个块。 那么,您在哪里将要查找的秘密添加到密文中? 目前您只是找到零填充,而不是秘密。并且零填充值为零 - 这不应该令人惊讶。
  • 显然我误解了攻击的概念,它不提供密钥恢复,而只是通过移动已知的加密块来泄露未知的加密字节。是这样吗?
  • 如果您认为可以通过与 ECB 相关的攻击来检索分组密码的密钥,那么您确实想错了方向。密钥受分组密码保护,因此无论操作模式如何(ECB、CBC 等)都无法检索。而且您的代码也不会尝试恢复秘密,因为它永远不会将秘密放入明文消息中。提示:尝试模拟两方时,请编程两方。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-06-25
  • 1970-01-01
  • 2019-04-18
相关资源
最近更新 更多