CbcModeTransform Class
Definition
- Namespace
- Bodu.Security.Cryptography
- Assembly
- Bodu.Security.Cryptography.dll
- Package
- Bodu.Security.Cryptography 1.2.0
- Source
- CbcModeTransform.cs
Applies the Cipher Block Chaining (CBC) mode transformation to an underlying IBlockCipher.
public sealed class CbcModeTransform : IBlockCipherModeTransform, IDisposable
- Inheritance
-
CbcModeTransform
- Implements
- Inherited Members
- Extension Methods
Examples
using System.Security.Cryptography;
using Bodu.Security.Cryptography;
// Most callers should set SymmetricAlgorithm.Mode = CipherBlockMode.CBC instead of using this directly.
using IBlockCipher cipher = new AesBlockCipher(key);
byte[] iv = RandomNumberGenerator.GetBytes(cipher.BlockSize / 8); // unique per message
IBlockCipherModeTransform cbc = new CbcModeTransform(cipher, iv);
byte[] ciphertext = new byte[paddedPlaintext.Length];
int written = cbc.Transform(paddedPlaintext, ciphertext, encrypt: true);
Remarks
Encryption computes Cᵢ = E(Pᵢ ⊕ Cᵢ₋₁) with C₋₁ = IV, and decryption inverts this as
Pᵢ = D(Cᵢ) ⊕ Cᵢ₋₁. See panel 2 of the diagram above: the dashed feedback line feeds each ciphertext
block forward into the XOR that precedes the next encryption, and the IV supplies that feedback for the very first
block.
The initialization vector must equal the cipher block size in length and should be unpredictable for each message; repeating an IV under the same key weakens confidentiality. The instance retains the most recent ciphertext block as the chaining value, so successive calls to Transform(ReadOnlySpan<byte>, Span<byte>, bool) continue the stream.
When to use CBC. The traditional confidentiality-only mode - the right pick when interoperating
with legacy protocols (TLS up to 1.2, JCE defaults, many file formats) or when an authenticated mode is impractical.
CBC requires plaintext to be a multiple of the block size, so it is almost always paired with
Pkcs7Padding. For new designs prefer GcmModeTransform or
EaxModeTransform, both of which authenticate as well as encrypt; CBC plus a separate MAC is fragile
and easy to misuse. Decryption with strippable padding is vulnerable to padding-oracle attacks. The pad-byte
validation is constant-time (each padding strategy's Unpad - see Pkcs7Padding - walks the full
final block with branchless masks), but that alone is not a complete defence - the depadded length still varies with
the pad count and an invalid block throws. Callers must authenticate the ciphertext (a MAC verified with
FixedTimeEquals(ReadOnlySpan<byte>, ReadOnlySpan<byte>),
or an AEAD mode) before depadding, so a padding failure is never observable to an attacker.
CBC is sequential - neither encryption nor decryption parallelizes across blocks within a single message. Random access into the ciphertext is not supported.
Constructors
CbcModeTransform(IBlockCipher, byte[])
Initializes a new instance of the CbcModeTransform class with the specified cipher and initialization vector.
public CbcModeTransform(IBlockCipher cipher, byte[] iv)
Parameters
cipherIBlockCipherThe block cipher over which CBC is applied.
ivbyte[]The initialization vector used as the chaining value for the first block. A defensive copy is taken.
Exceptions
- ArgumentNullException
Thrown if
cipherorivis null.
Methods
Dispose()
Releases the resources used by this instance and zeroes the running chaining vector so that key-equivalent IV state does not linger in memory after disposal. The underlying IBlockCipher is not disposed by this type - ownership remains with the caller.
public void Dispose()
Remarks
Idempotent.
Transform(ReadOnlySpan<byte>, Span<byte>, bool)
Transforms input under the mode's chaining strategy and writes the result to
output.
public int Transform(ReadOnlySpan<byte> input, Span<byte> output, bool encrypt)
Parameters
inputReadOnlySpan<byte>The input data to transform. Its length must be a positive multiple of the underlying cipher block size.
outputSpan<byte>The destination span. Its length must be greater than or equal to the length of
input.encryptbool
Returns
- int
The number of bytes written to
output.
Exceptions
- ArgumentException
Thrown when
input's length is not a multiple of the block size or whenoutputis too small.
Applies to
| Product | Versions |
|---|---|
| .NET | 8, 10 |