PKCS#7 填充是用偽隨機數生成器生成的嗎?
讓我們來看看這個 PHP 程式碼。我們使用 libsodium 和 libsodium-php。你有
$text
,$senderPrivateKey
和. 後者顯然是通過使用 Sodium 創建的:$recipientPublicKey``$nonce
$nonce = \Sodium\randombytes_buf($size);
現在這是添加 PKCS#7 填充的程式碼:
/* determine random amount of PKCS7 padding */ $padBytes = mt_rand(1, 255); /* append padding */ $textBytes .= str_repeat(chr($padBytes), $padBytes);
之後,使用
\Sodium\crypto_box_keypair_from_secretkey_and_publickey
和對其進行加密\Sodium\crypto_box
。那麼這裡可以使用mt_rand嗎?我的意思是在 PHP 文件中,不鼓勵將其用於任何“加密目的”。但是這裡它僅用於選擇(“隨機”)字元和填充的長度。
那麼這安全嗎?使用
openssl_random_pseudo_bytes()
,random_bytes
(在 PHP 7 中)或 libsodiums\Sodium\randombytes_buf
(就像它用於 nonce 一樣)會更安全嗎?這是 PKCS#7 的正確實現嗎?特別是因為相同的變數用於填充的長度和字元。**編輯:**因為這裡有一些令人困惑的更多資訊:實際上這個實現只是應該隱藏文件大小(尤其是短數據)以防止攻擊者猜測純文字消息。這是在一些與 Threema 相關的開源庫中實現的,這裡有一個關於此的問題。因此,基本上在 Threema 客戶端中使用了加密安全的 RNG,在此範例中使用了不安全的 PRNG。這就是這個問題的意義所在:在這裡使用 PRNG 是不是不太安全?
如果填充的目的是讓被動攻擊者只了解一個範圍而不是確切的消息長度,請不要使用
real_len + rand(max_padlen)
. 將填充消息的長度設置為給定塊大小的倍數會更有效。如果您的協議有足夠的自由度以允許填充長度的較大變化,您可以使用隨機長度,但要注意重放攻擊。如果對於給定的問題,始終發送相同的響應,則可以多次發送該問題,以便最終推斷出實際響應長度。為了減輕這種情況,對於給定的問題,填充長度應該始終相同。可以使用一個簡單的 PRF 來實現這一點。