计数器模式

密碼學中，區塊密碼的**工作模式**（mode of operation）允許使用同一個區塊密碼密鑰對多於一塊的資料進行加密，並保證其安全性。
區塊密碼自身只能加密長度等於密碼區塊長度的單塊資料，若要加密變長資料，則資料必須先被劃分為一些單獨的密碼塊。通常而言，最後一塊資料也需要使用合適填充方式將資料擴充到符合密碼塊大小的長度。一種工作模式描述了加密每一資料塊的過程，並常常使用基於一個通常稱為初始化向量的附加輸入值以進行隨機化，以保證安全。

工作模式主要用來進行加密和認證。
對加密模式的研究曾經包含資料的完整性保護，即在某些資料被修改後的情況下密碼的誤差傳播特性。後來的研究則將完整性保護作為另一個完全不同的，與加密無關的密碼學目標。部分現代的工作模式用有效的方法將加密和認證結合起來，稱為認證加密模式。

雖然工作模式通常應用於對稱加密，它亦可以應用於公鑰加密，例如在原理上對 RSA 進行處理，但在實用中，公鑰密碼學通常不用於加密較長的資訊，而是使用結合對稱加密和公鑰加密的混合加密方案。

## 歷史和標準化

最早出現的工作模式，ECB，CBC，OFB 和 CFB 可以追溯到 1981 年。2001 年，NIST 修訂了其早先發布的工作模式工作列表，加入了 AES，並加入了 CTR 模式。最後，在 2010 年 1 月，NIST 加入了 XTS-AES，而其餘的可信模式並沒有為 NIST 所認證。例如 CTS 是一種密文竊取的模式，許多常見的密碼學執行庫提供了這種模式。

ECB，CBC，OFB，CFB，CTR 和 XTS 模式僅僅提供了機密性；為了保證加密資訊沒有被意外修改或惡意篡改，需要採用分離的訊息驗證碼，例如 CBC-MAC。密碼學社群認識到了對專用的保證完整性的方法的需求，NIST 因此提出了 HMAC，CMAC 和 GMAC。HMAC 在 2002 年通過了認證，CMAC 在 2005 年通過，GMAC 則在 2007 年被標準化。

在發現將認證模式與加密模式聯合起來的難度之後，密碼學社群開始研究結合了加密和認證的單一模式，這種模式被稱為認證加密模式（AE，Authenticated Encryption），或稱為 authenc。AE 模式的例子包括 CCM，GCM，CWC，EAX，IAPM 和 OCB。

現在，工作模式為許多國家和國內的標準認證實體所定義，其中最有影響力的來源是美國的 NIST，而其它有影響力的組織包括 ISO，IEC，IEEE，美國的 ANSI，以及 IETF。

## 初始化向量（IV）

初始化向量（IV，Initialization Vector）是許多工作模式中用於將加密隨機化的一個位塊，由此即使同樣的明文被多次加密也會產生不同的密文，避免了較慢的重新產生金鑰的過程。

初始化向量與金鑰相比有不同的安全性需求，因此 IV 通常無須保密，然而在大多數情況中，不應當在使用同一金鑰的情況下兩次使用同一個 IV。對於 CBC 和 CFB，重用 IV 會導致泄露明文首個塊的某些資訊，亦包括兩個不同訊息中相同的字首。對於 OFB 和 CTR 而言，重用 IV 會導致完全失去安全性。另外，在 CBC 模式中，IV 在加密時必須是無法預測的；特別的，在許多實現中使用的產生 IV 的方法，例如 SSL2.0 使用的，即採用上一個訊息的最後一塊密文作為下一個訊息的 IV，是不安全的。

## 填充

塊密碼只能對確定長度的資料塊進行處理，而訊息的長度通常是可變的。因此部分模式（即 ECB 和 CBC）需要最後一塊在加密前進行填充。有數種填充方法，其中最簡單的一種是在明文的最後填充空字元以使其長度為塊長度的整數倍，但必須保證可以恢復明文的原始長度；例如，若明文是 C 語言風格的字串，則只有串尾會有空字元。稍微複雜一點的方法則是原始的 DES 使用的方法，即在資料後添加一個 1 位，再添加足夠的 0 位直到滿足塊長度的要求；若訊息長度剛好符合塊長度，則添加一個填充塊。最複雜的則是針對 CBC 的方法，例如密文竊取，殘塊終結等，不會產生額外的密文，但會增加一些複雜度。布魯斯・施奈爾和尼爾斯・弗格森提出了兩種簡單的可能性：添加一個值為 128 的位元組（十六進位的 80），再以 0 位元組填滿最後一個塊；或向最後一個塊填充 _n_ 個值均為 _n_ 的位元組。

CFB，OFB 和 CTR 模式不需要對長度不為密碼塊大小整數倍的訊息進行特別的處理。因為這些模式是通過對塊密碼的輸出與明文進行互斥或工作的。最後一個明文塊（可能是不完整的）與金鑰流塊的前幾個位元組互斥或後，產生了與該明文塊大小相同的密文塊。串流加密法的這個特性使得它們可以應用在需要密文和明文資料長度嚴格相等的場合，也可以應用在以流形式傳輸資料而不便於進行填充的場合。

## 常用模式

### 電子密碼本（ECB）

最簡單的加密模式即為**電子密碼本**（Electronic codebook，ECB）模式。需要加密的訊息按照塊密碼的塊大小被分為數個塊，並對每個塊進行獨立加密。

本方法的缺點在於同樣的明文塊會被加密成相同的密文塊；因此，它不能很好的隱藏資料模式。在某些場合，這種方法不能提供嚴格的資料保密性，因此並不推薦用於密碼協定中。下面的例子顯示了 ECB 在密文中顯示明文的模式的程度：該圖像的一個點陣圖版本（左圖）通過 ECB 模式可能會被加密成中圖，而非 ECB 模式通常會將其加密成右圖。

右圖是使用 CBC，CTR 或任何其它的更安全的模式加密左圖可能產生的結果 —— 與隨機噪聲無異。注意右圖看起來的隨機性並不能表示圖像已經被安全的加密；許多不安全的加密法也可能產生這種「隨機的」輸出。

ECB 模式也會導致使用它的協定不能提供資料完整性保護，易受到重放攻擊的影響，因為每個塊是以完全相同的方式解密的。例如，「夢幻之星線上：藍色脈衝」線上電子遊戲使用 ECB 模式的 Blowfish 密碼。在金鑰交換系統被破解而產生更簡單的破解方式前，作弊者通過重複傳送加密的「殺死怪物」訊息包以非法的快速增加經驗值。

### 密碼塊連結（CBC）

1976 年，IBM 發明了**密碼區塊連結**（CBC，Cipher-block chaining）模式。在 CBC 模式中，每個明文塊先與前一個密文塊進行互斥或後，再進行加密。在這種方法中，每個密文塊都依賴於它前面的所有明文塊。同時，為了保證每條訊息的唯一性，在第一個塊中需要使用初始化向量。

若第一個塊的下標為 1，則 CBC 模式的加密過程為

　
: $C_{i}=E_{K}(P_{i}\oplus C_{i-1}),$

　
: $C_{0}=IV$

而其解密過程則為

　
: $P_{i}=D_{K}(C_{i})\oplus C_{i-1},$

　
: $C_{0}=IV$

CBC 是最為常用的工作模式。它的主要缺點在於加密過程是串行的，無法被並列化，而且訊息必須被填充到塊大小的整數倍。解決後一個問題的一種方法是利用密文竊取。

注意在加密時，明文中的微小改變會導致其後的全部密文塊發生改變，而在解密時，從兩個鄰接的密文塊中即可得到一個明文塊。因此，解密過程可以被並列化，而解密時，密文中一位的改變只會導致其對應的明文塊完全改變和下一個明文塊中對應位發生改變，不會影響到其它明文的內容。

### 填充密碼塊連結（PCBC）

**填充密碼塊連結**（**PCBC**，Propagating cipher-block chaining）或稱為**明文密碼塊連結**（Plaintext cipher-block chaining），是一種可以使密文中的微小更改在解密時導致明文大部分錯誤的模式，並在加密的時候也具有同樣的特性。

加密和解密演算法如下：

　
: $C_{i}=E_{K}(P_{i}\oplus P_{i-1}\oplus C_{i-1}),P_{0}\oplus C_{0}=IV$

　
: $P_{i}=D_{K}(C_{i})\oplus P_{i-1}\oplus C_{i-1},P_{0}\oplus C_{0}=IV$

PCBC 主要用於 Kerberos v4 和 WASTE 中，而在其它場合的應用較少。對於使用 PCBC 加密的訊息，互換兩個鄰接的密文塊不會對後續塊的解密造成影響。正因為這個特性，Kerberos v5 沒有使用 PCBC。

### 密文回饋（CFB）

**密文回饋**（CFB，Cipher feedback）模式類似於 CBC，可以將塊密碼變為自同步的串流加密法；工作過程亦非常相似，CFB 的解密過程幾乎就是顛倒的 CBC 的加密過程：

　
: $C_{i}=E_{K}(C_{i-1})\oplus P_{i}$

　
: $P_{i}=E_{K}(C_{i-1})\oplus C_{i}$

　
: $C_{0}=\ {\mbox{IV}}$

上述公式是描述的是最簡單的 CFB，在這種模式下，它的自同步特性僅僅與 CBC 相同，即若密文的一整塊發生錯誤，CBC 和 CFB 都仍能解密大部分資料，而僅有一位資料錯誤。若需要在僅有了一位或一位元組錯誤的情況下也讓模式具有自同步性，必須每次只加密一位或一位元組。可以將移位暫存器作為塊密碼的輸入，以利用 CFB 的自同步性。

為了利用 CFB 製作一種自同步的，可以處理任意位情況錯誤的串流加密法，需要使用一個與塊的大小相同的移位暫存器，並用 IV 將暫存器初始化。然後，將暫存器內容使用塊密碼加密，然後將結果的最高 _x_ 位與明文的 _x_ 進行互斥或，以產生密文的 _x_ 位。下一步將生成的 _x_ 位密文移入暫存器中，並對下面的 _x_ 位明文重複這一過程。解密過程與加密過程相似，以 IV 開始，對暫存器加密，將結果的高 _x_ 與密文互斥或，產生 _x_ 位明文，再將密文的下面 _x_ 位移入暫存器。

下式中 Si 是移位暫存器的第 _i_ 個狀態，a << x 是指將 _a_ 移位 _x_ 位，head (a, x) 是指 _a_ 的高 _x_ 位，_n_ 則是指 IV 的位數。

　
: $C_{i}={\mbox{head}}(E_{K}(S_{i-1}),x)\oplus P_{i}$

　
: $P_{i}={\mbox{head}}(E_{K}(S_{i-1}),x)\oplus C_{i}$

　
: $S_{i}=\ ((S_{i-1}<<x)+C_{i}){\mbox{ mod }}2^{n}$

　
: $S_{0}=\ {\mbox{IV}}$

若密文的 _x_ 位發生錯誤，則密碼在移位暫存器恢復與加密時的狀態相同之前，輸出不正確的結果，而當暫存器狀態恢復後，密碼即可以重新同步，恢復正常輸出，因此最多只有一塊資料發生錯誤。

與 CBC 相似，明文的改變會影響接下來所有的密文，因此加密過程不能並列化；而同樣的，與 CBC 類似，解密過程是可以並列化的。在解密時，密文中一位資料的改變僅會影響兩個明文塊：對應明文塊中的一位資料與下一塊中全部的資料，而之後的資料將恢復正常。

CFB 擁有一些 CBC 所不具備的特性，這些特性與 OFB 和 CTR 的流模式相似：只需要使用塊密碼進行加密操作，且訊息無需進行填充（雖然密文竊取也允許資料不進行填充）。

### 輸出回饋（OFB）

**輸出回饋**模式（Output feedback, OFB）可以將塊密碼變成同步的串流加密法。它產生金鑰流的塊，然後將其與明文塊進行互斥或，得到密文。與其它串流加密法一樣，密文中一個位的翻轉會使明文中同樣位置的位也產生翻轉。這種特性使得許多錯誤校正碼，例如奇偶校驗位，即使在加密前計算，而在加密後進行校驗也可以得出正確結果。

由於 XOR 操作的對稱性，加密和解密操作是完全相同的：

　
: $C_{i}=P_{i}\oplus O_{i}$

　
: $P_{i}=C_{i}\oplus O_{i}$

　
: $O_{i}=\ E_{K}(O_{i-1})$

　
: $O_{0}=\ {\mbox{IV}}$

每個使用 OFB 的輸出塊與其前面所有的輸出塊相關，因此不能並列化處理。然而，由於明文和密文只在最終的互斥或過程中使用，因此可以事先對 IV 進行加密，最後並列的將明文或密文進行並列的互斥或處理。

可以利用輸入全 0 的 CBC 模式產生 OFB 模式的金鑰流。這種方法十分實用，因為可以利用快速的 CBC 硬體實現來加速 OFB 模式的加密過程。

### 計數器模式（CTR）

　
: 注意：CTR 模式（Counter mode，CM）也被稱為 ICM 模式（Integer Counter Mode，整數計數模式）和 SIC 模式（Segmented Integer Counter）。

與 OFB 相似，CTR 將塊密碼變為串流加密法。它通過遞增一個加密計數器以產生連續的金鑰流，其中，計數器可以是任意保證長時間不產生重複輸出的函式，但使用一個普通的計數器是最簡單和最常見的做法。使用簡單的、定義好的輸入函式是有爭議的：批評者認為它「有意的將密碼系統暴露在已知的、系統的輸入會造成不必要的風險」。目前，CTR 已經被廣泛的使用了，由輸入函式造成的問題被認為是使用的塊密碼的缺陷，而非 CTR 模式本身的弱點。無論如何，有一些特別的攻擊方法，例如基於使用簡單計數器作為輸入的硬體差錯攻擊。

CTR 模式的特徵類似於 OFB，但它允許在解密時進行隨機存取。由於加密和解密過程均可以進行並列處理，CTR 適合運用於多處理器的硬體上。

注意圖中的「nonce」與其它圖中的 IV（初始化向量）相同。IV、亂數和計數器均可以通過連接，相加或互斥或使得相同明文產生不同的密文。

## 誤差傳播

在訊息鑑別碼和認證加密的廣泛應用之前，常常有人討論塊密碼工作模式的「誤差傳播」特性，作為工作模式效能的一部分。例如，若密文傳輸中一個資料塊的錯誤會導致採用 ECB 模式生成的明文中同樣一個塊的錯誤，而 CBC 模式中會導致兩個明文塊出錯。

有人認為這樣的特性在應對隨機誤差（例如傳輸噪聲）時會是有益的，而還有人認為這樣的特性使得攻擊者更容易篡改訊息的一部分。

無論如何，若使用了適當的完整性保護措施，這樣的誤差很可能會導致整個訊息重發。若需要應對隨機誤差，則應當在傳送密文之前增加錯誤校正碼。

## 認證加密

一些工作模式在設計中希望將保密性和認證性結合起來，例如 XCBC，ACBC，APM，OCB，EAX，CWC，CCM 和 GCM。認證加密模式被可以分為單次處理和兩次處理兩種類型。然而，對密碼學使用者社群而言，不幸的是，許多單次處理的認證加密演算法，例如 OCB，是受專利所保護的。

另外，有的模式也允許為未加密的關聯資料進行認證，因此被稱為 AEAD（Authenticated-Encryption with Associated-Data，用於關聯資料的認證加密）。例如，EAX 是一種兩次處理的 AEAD 方法，而 OCB 模式是單次的。

## 其它模式和密碼學概念

除了上文中提到的模式以外，還有很多其它的塊密碼工作模式。有的被公眾所接受，有其詳細描述了，甚至被標準化了，並在使用中；而有的則被認為是不安全的，而從未使用過；另外一些則並沒有被分類為保密，認證或簽章加密，例如金鑰回饋模式（KFM，Key Feedback Mode）和 AES-hash。NIST 維護著一張塊密碼工作模式列表。

磁碟加密通常使用特殊目的、專門設計的模式。可以調節的小資料塊加密模式（LRW，XEX 和 XTS）和大數據塊的模式（CMC 和 EME）是設計用於加密磁碟區塊的。

塊密碼也可以用於其它加密協定中，在這些協定中，塊密碼的使用方式與前述工作模式相似。在一切協定中，為了保證其安全性，必須在構建工作模式時特別注意。

有數種方法可以用塊密碼構建密碼雜湊函式，參見單向壓縮函式。

訊息鑑別碼（MAC）通常由塊密碼得到，例如 CBC-MAC，OMAC 和 PMAC。

認證加密也採用塊密碼作為其中的一部，其同時使用加密和 MAC 以提供保密性和資料完整性，例如 IAPM，CCM，CWC，EAX，GCM 和 OCB。

## 參考文獻