Openssl

ChaCha20-Poly1305 測試向量

  • July 30, 2017

我試圖使用 OpenSSL 1.1(通過 Ruby)來驗證這個 IETF 草案中的 ChaCha20-Poly1305 測試向量:https ://datatracker.ietf.org/doc/html/draft-agl-tls-chacha20poly1305-04#section- 7

這裡引用了相關的測試向量:

The following block contains a test vector for the
AEAD_CHACHA20_POLY1305 algorithm.  The first four lines consist of
the standard inputs to an AEAD algorithm and the last line contains
the encrypted and authenticated result.
KEY:    4290bcb154173531f314af57f3be3b5006da371ece272afa1b5dbdd110
       0a1007
INPUT:  86d09974840bded2a5ca
NONCE:  cd7cf67be39c794a
AD:     87e229d4500845a079c0
OUTPUT: e3e446f7ede9a19b62a4677dabf4e3d24b876bb284753896e1d6

這給了我一個 8 字節的隨機數。但是當我嘗試執行這個測試時,我很快遇到了一個問題:

cipher = OpenSSL::Cipher.new("chacha20-poly1305")
cipher.encrypt
cipher.key = ["4290bcb154173531f314af57f3be3b5006da371ece272afa1b5dbdd1100a1007"].pack("H*")
cipher.iv = ["cd7cf67be39c794a"].pack("H*")

ArgumentError: iv must be 12 bytes
       from (irb):81:in `iv='
       from (irb):81
       from ~/.rvm/rubies/ruby-2.4.0/bin/irb:11:in `<main>'

為什麼 OpenSSL 堅持使用 12 字節的隨機數,但規範草案卻給了我一個 8 字節的隨機數?我還在學習 ChaCha20 和 Poly1305,所以我確定我缺少一些基本的東西。

正如所指出的,對於完整的圖片,您應該使用最終的 RFC,而不是草稿。這裡有兩個相關的 RFC:

在 RFC 7539 的第 2.6 節中,有一些關於 nonce 的解釋。隨機數的長度必須正好為 96 位(12 字節);但是,會出現以下文本:

The protocol will specify a 96-bit or 64-bit nonce.  This MUST be
unique per invocation with the same key, so it MUST NOT be
randomly generated.  A counter is a good way to implement this,
but other methods, such as a Linear Feedback Shift Register (LFSR)
are also acceptable.  ChaCha20 as specified here requires a 96-bit
nonce.  So if the provided nonce is only 64-bit, then the first 32
bits of the nonce will be set to a constant number.  This will
usually be zero, but for protocols with multiple senders it may be
different for each sender, but should be the same for all
invocations of the function with the same key by a particular
sender.

這就是 RFC 7539 第 2.8.2 節中的測試向量顯示以下內容的原因:

IV:
000  40 41 42 43 44 45 46 47                          @ABCDEFG

32-bit fixed-common part:
000  07 00 00 00 

這些是 64 位 IV 和 32 位“固定公共部分”,它們旨在組裝(連接)成算法所需的 96 位值。

但是,如果您查看 RFC 7905,您會發現 TLS 中發生的事情有點不同:

AEAD_CHACHA20_POLY1305 requires a 96-bit nonce, which is formed as
follows:

1.  The 64-bit record sequence number is serialized as an 8-byte,
   big-endian value and padded on the left with four 0x00 bytes.

2.  The padded sequence number is XORed with the client_write_IV
   (when the client is sending) or server_write_IV (when the server
   is sending).

換句話說,從握手中生成一個完整的 96 位(12 字節)值,並將記錄序列號異或到最後 8 個字節。另一種設計更符合 RFC 7539 中解釋的方法,將握手期間生成的 32(4 字節)值與 64 位(8 字節)記錄計數器連接起來。然而,RFC 7905 的設計者發現它適合使用 XOR 方法,這可以被認為是使不同 TLS 連接之間的 nonce 重用的可能性更小(這並不重要,因為不同的 TLS 連接也使用不同的加密密鑰)。

引用自:https://crypto.stackexchange.com/questions/50504