代码之家  ›  专栏  ›  技术社区  ›  HostileFork says dont trust SE

TLS 1.2的“解密错误”更改密码规范,但正确读取MAC

  •  12
  • HostileFork says dont trust SE  · 技术社区  · 6 年前

    我正在尝试将一个旧的TLS1.0实现(我没有编写)升级到最新的TLS1.2版本。

    作为第一步,我集成了TLS 1.1 putting the plaintext initialization vector in the record https://example.com 在TLS 1.1以及SSL实验室中 viewMyClient.html .

    然后我适应了TLS 1.2对伪随机函数的修改(为了最实际的目的) P_SHA256 而不是(更复杂和奇怪) half and half MD5/SHA1 rigamarole

    但尽管如此,在发送ClientKeyExchange之后->ChangeCipherSpec消息,我从服务器收到“解密错误” https://google.com 或者任何我尝试过的东西) . 我想ChangeCipherSpec消息正在加密 一个字节 ,将其放入带有填充和MAC的消息中,等等。

    如果我将MAC随机调整一个字节,它会返回到抱怨无效的MAC。 使我困惑的是 the MAC itself is encrypted as part of GenericBlockCipher

    struct {
        opaque IV[SecurityParameters.record_iv_length];
        block-ciphered struct {
            opaque content[TLSCompressed.length];
            opaque MAC[SecurityParameters.mac_length]; // <-- server reads this fine!
            uint8 padding[GenericBlockCipher.padding_length];
            uint8 padding_length;
        };
    } GenericBlockCipher;
    

    更新: FWIW,我添加了一个Wireshark日志,记录了 https://example.com ,以及正在运行的1.1会话的日志,该会话运行的是相同的代码,不包括P\ U SHA256 MAC更新:

    http://hostilefork.com/media/shared/stackoverflow/example-com-tls-1.2.pcapng (失败) http://hostilefork.com/media/shared/stackoverflow/example-com-tls-1.1.pcapng (成功)

    (规范说“接收器必须检查这个填充,并且必须使用bad \u record \u mac警报来指示填充错误”,所以这是意料之中的。) 如果我破坏了我用来加密的消息中的client iv(只需在传输的版本中放入一个坏字节),那么这样做也会给我带来坏记录MAC。我希望这也会破坏解密。

    所以我对可能的问题感到困惑:

    • 必须 已经解密了。它是如何得到正确的MAC-和-有一个解密错误?
    • 密码套件是一个旧的(TLS\u RSA\u与\u AES\u 256\u CBC\u SHA),但我只是一次解决一个问题…如果我没有弄错,那应该没关系。

    有相关经验的人对tls1.2如何对在tls1.1中工作的代码施加干扰有理论吗? (也许有人对一个代码库做过类似的更新,为了让它正常工作,我改变了不止两件事?)

    2 回复  |  直到 6 年前
        1
  •  4
  •   HostileFork says dont trust SE    6 年前

    事实上这辆车没什么问题 ChangeCipherSpec 信息。实际上是 Finished message verify_data 在该消息中,该消息与预期哈希不匹配(尽管加密/解密本身是正确的)。

    但Wireshark日志中令人困惑的是 EncryptedHandshakeMessage " 这使它看起来像某种描述ChangeCipherSpec的标记或标签,但事实并非如此。那条消息实际上根本没有加密。


    “希望有人有过将TLS 1.0或1.1升级到1.2的经验,并且可能由于更改的数量不超过P\U SHA256 MAC和版本号不一致而遇到类似的问题”

    它们只提到了更新文档中MD5/SHA1组合所需的三个位置中的两个 "changes from TLS 1.1" section

    • 数字签名元素中的MD5/SHA-1组合已替换为单个哈希。有符号元素现在包含一个字段,该字段显式指定所使用的哈希算法。

    (注意:第二种方法适用于证书,如果您还没有进行证书检查,那么您现在还没有进行证书检查。)

    他们在那部分没有提到的是 放置MD5/SHA-1组合更改,这是用于 验证\u数据 完成了 信息。但是,这一点也是对TLS1.1的一个更改,在文档的后面进行了更深入的描述 section 7.4.9 :

    哈希表示握手消息的哈希。对于第5节中定义的PRF,哈希必须是用作PRF基础的哈希。任何定义不同PRF的密码套件也必须定义要在完成的计算中使用的哈希。”

    (另请注意,密码套件可以将verify\u数据的长度指定为12个字节以上,尽管规范中没有提到这样做的)


    基督教青年会。但我所做的只是将OpenSSL构建为一个静态调试库,并将其链接到一个简单的服务器。然后我添加了断点和插装,以查看它有什么问题( GDB wasn't letting me step into the shared library, for some reason

    大约在2018年9月30日,在普通linux机器上:

    • git://git.openssl.org/openssl.git
    • ./config no-shared no-asm -g3 -O0 -fno-omit-frame-pointer -fno-inline-functions no-ssl2 no-ssl3
    • make

    我使用的简单服务器来自 Simple TLS Server . 针对静态库进行编译:

    • gcc -g -O0 simple.c -o simple -lssl -lcrypto -ldl -lpthread

    localhost

    openSSL sign https_client certificate with CA

    然后我换了衣服 cert.pem => rootCA.pem key.pem => rootCA.key 在简单的服务器代码中。我能做到:

    wget https://localhost:4433 --no-check-certificate
    

    test 作为回应。所以接下来的问题就是看我的客户是哪里导致了失败。

        2
  •  1
  •   Afshin    6 年前

    我能想到造成这个问题的两种不同情况:

    1. IV 仅影响解密的第一个块 CBC 模式,所以如果您的内容超过16字节( AES 块大小), MAC 部分数据将被正确解密。
    2. 如果使用的填充结构不正确,则解密时可能会出错(因为填充验证失败),但内容将正确解密。