Class S100Cipher
- Namespace
- EncDotNet.S100.ExchangeSets.Protection
- Assembly
- EncDotNet.S100.ExchangeSets.dll
Implements the symmetric (confidentiality) cryptography of the S-100 Part 15 Data Protection Scheme: AES-128 in CBC mode with the modified initialization vector handling, plus the single-block key-wrapping used for cell keys and hardware identifiers.
public static class S100Cipher
- Inheritance
-
S100Cipher
- Inherited Members
Remarks
S-100 Edition 5.2.1 Part 15 §15-6. The scheme always uses a 128-bit key (§15-6.2.1) and PKCS#7 padding (§15-6.2.2). Dataset files use a modified CBC mode (§15-6.2.4): the plaintext is prepended with one random block and encrypted under a random initialization vector that is not transmitted; on decryption an arbitrary IV is used and the first recovered plaintext block is discarded.
Cell keys and hardware identifiers are exactly one AES block (16 bytes) and are wrapped with a single-block encryption with no chaining or padding (§15-7.3.1.1, §15-7.4.4).
Fields
BlockSize
The AES block size in bytes (128 bits).
public const int BlockSize = 16
Field Value
KeyLength
The S-100 Part 15 key length in bytes (128 bits).
public const int KeyLength = 16
Field Value
Methods
DecryptBlock(ReadOnlySpan<byte>, ReadOnlySpan<byte>)
Decrypts a single 16-byte block with AES-128 (no chaining, no padding). This is the inverse of EncryptBlock(ReadOnlySpan<byte>, ReadOnlySpan<byte>) and is used to unwrap a cell key from an encrypted key with the hardware id (§15-7.4.4) or a hardware id from a user permit with the manufacturer key (§15-7.3.1.1).
public static byte[] DecryptBlock(ReadOnlySpan<byte> block, ReadOnlySpan<byte> key)
Parameters
blockReadOnlySpan<byte>The 16-byte ciphertext block.
keyReadOnlySpan<byte>The 16-byte key.
Returns
- byte[]
The 16-byte plaintext block.
DecryptDataset(ReadOnlySpan<byte>, ReadOnlySpan<byte>)
Decrypts a dataset (or other product file) that was encrypted with the S-100 Part 15 modified CBC mode.
public static byte[] DecryptDataset(ReadOnlySpan<byte> ciphertext, ReadOnlySpan<byte> cellKey)
Parameters
ciphertextReadOnlySpan<byte>The encrypted file content.
cellKeyReadOnlySpan<byte>The 16-byte cell (product) key.
Returns
- byte[]
The decrypted bytes with the random prefix block removed.
Remarks
S-100 Edition 5.2.1 Part 15 §15-6.2.4. The ciphertext is decrypted with AES-128-CBC under an arbitrary (zero) IV — which only corrupts the first plaintext block — the PKCS#7 padding is removed, and the leading random block is discarded, yielding the original (still compressed, if the product specification applies compression) bytes.
Exceptions
- CryptographicException
The ciphertext is not a positive multiple of the block size, is shorter than the mandatory random block, or has invalid padding.
EncryptBlock(ReadOnlySpan<byte>, ReadOnlySpan<byte>)
Encrypts a single 16-byte block with AES-128 (no chaining, no padding). Used to wrap a hardware id with a manufacturer key (§15-7.3.1.1) or a cell key with a hardware id (§15-7.4.4).
public static byte[] EncryptBlock(ReadOnlySpan<byte> block, ReadOnlySpan<byte> key)
Parameters
blockReadOnlySpan<byte>The 16-byte plaintext block.
keyReadOnlySpan<byte>The 16-byte key.
Returns
- byte[]
The 16-byte ciphertext block.
EncryptDataset(ReadOnlySpan<byte>, ReadOnlySpan<byte>)
Encrypts bytes with the S-100 Part 15 modified CBC mode. Provided to support round-trip testing and synthetic fixture generation; production reading only needs DecryptDataset(ReadOnlySpan<byte>, ReadOnlySpan<byte>).
public static byte[] EncryptDataset(ReadOnlySpan<byte> plaintext, ReadOnlySpan<byte> cellKey)
Parameters
plaintextReadOnlySpan<byte>The bytes to encrypt (already compressed, if applicable).
cellKeyReadOnlySpan<byte>The 16-byte cell (product) key.
Returns
- byte[]
The encrypted file content.
Remarks
S-100 Edition 5.2.1 Part 15 §15-6.2.4. A cryptographically random block
is prepended to plaintext, the result is PKCS#7-padded
and encrypted with AES-128-CBC under a random IV that is intentionally
not returned.
EncryptDataset(ReadOnlySpan<byte>, ReadOnlySpan<byte>, ReadOnlySpan<byte>, ReadOnlySpan<byte>)
Encrypts bytes with the S-100 Part 15 modified CBC mode using the given prefix block and initialization vector instead of random ones, so the output is reproducible. For synthetic test fixtures only.
public static byte[] EncryptDataset(ReadOnlySpan<byte> plaintext, ReadOnlySpan<byte> cellKey, ReadOnlySpan<byte> prefixBlock, ReadOnlySpan<byte> iv)
Parameters
plaintextReadOnlySpan<byte>The bytes to encrypt (already compressed, if applicable).
cellKeyReadOnlySpan<byte>The 16-byte cell (product) key.
prefixBlockReadOnlySpan<byte>The 16-byte block prepended to the plaintext.
ivReadOnlySpan<byte>The 16-byte initialization vector, which is not transmitted.
Returns
- byte[]
The encrypted file content.
Remarks
S-100 Edition 5.2.1 Part 15 §15-6.2.4 requires the prefix block and the IV to be random; a data server must use EncryptDataset(ReadOnlySpan<byte>, ReadOnlySpan<byte>). Fixed values here let generated fixtures diff cleanly between runs.
The output decrypts with DecryptDataset(ReadOnlySpan<byte>, ReadOnlySpan<byte>) like any other, because decryption discards the first block whatever the IV.