Block Sizes and Padding in A Most Amazing Machine

Do your eyes glaze over when someone mentions the size of encryption and the block size? Well, it’s important as the security of our data…

Block Sizes and Padding in A Most Amazing Machine

Do your eyes glaze over when someone mentions the size of encryption and the block size? Well, it’s important as the security of our data is dependent on the size of the key, and are data is encrypted within blocksize.

Many older encryption methods used a 64-bit block size, which meant that they would read in 8 characters (or eight 8-bit values) into a block and then encrypt that. Common methods that use these block sizes are DES and 3-DES. Most modern symmetric key methods, such as AES, use a 128-bit block size, which means we read in 16 characters at a time. In AES we actually create a 4x4 matrix, and then swap rows and columns, and then put them through an S-box and P-box:

But what happens if we don’t fill up all the last block? Well padding is used in a block cipher where we fill up the blocks with padding bytes. AES uses 128-bits (16 bytes), and DES uses 64-bit blocks (8 bytes). The main padding methods are:

  • CMS (Cryptographic Message Syntax). This pads with the same value as the number of padding bytes. Defined in RFC 5652, PKCS#5, PKCS#7 (X.509 certificate) and RFC 1423 PEM.
  • Bit. This pads with 0x80 (10000000) followed by zero (null) bytes. Defined in ANSI X.923 and ISO/IEC 9797–1.
  • ZeroLength. This pads with zeros except for the last byte which is equal to the number (length) of padding bytes.
  • Null. This pads will NULL bytes. This is only used with ASCII text.
  • Space. This pads with spaces. This is only used with ASCII text.
  • Random. This pads with random bytes with the last byte defined by the number of padding bytes.

If we use “hello”, then we must pad to 16 bytes, this means there are 11 padding bytes (0xB) to give [here]:

After padding (CMS): 68656c6c6f0b0b0b0b0b0b0b0b0b0b0b
Cipher (ECB): 0a7ec77951291795bac6690c9e7f4c0d
decrypt: hello
After padding (Bit): 68656c6c6f8000000000000000000000
Cipher (ECB): 731abffc2e3b2c2b5caa9ca2339344f9
decrypt: hello
After padding (ZeroLen): 68656c6c6f000000000000000000000a
Cipher (ECB): d28e2f7e8e44e068732b292bde444245
decrypt: hello�
After padding (Null): 68656c6c6f0000000000000000000000
Cipher (ECB): 444797422460453d95856eb2a1520ece
decrypt: hello
After padding (Space): 68656c6c6f0000000000000000000000
Cipher (ECB): 444797422460453d95856eb2a1520ece
decrypt:
After padding (Random): 68656c6c6ffc6ecfd884a38798d62a0a
Cipher (ECB): f690c7e8cd357c7fabfb1b5498eec12e
decrypt: helloõ

For random padding we see the padding is After padding (Random): “68656c6c6ffc6ecfd884a38798d62a0a” where “68656c6c6” is the message (“hello”), “ffc6ecfd884a38798d62a” is the random collection of bytes, and “0a” identifies that there are 10 bytes used for the random data padding.

If we use “hello123”, then we must pad to 8 bytes, this means there are 8 padding bytes (0x8) to give:

After padding (CMS): 68656c6c6f3132330808080808080808
Cipher (ECB): aa9accd8acdb337fe6dba0bbfe426070
decrypt: hello123
After padding (Bit): 68656c6c6f3132338000000000000000
Cipher (ECB): 0f6c3077e6838ab6b5a1dc1ee6afd8e3
decrypt: hello123
After padding (ZeroLen): 68656c6c6f3132330000000000000007
Cipher (ECB): 38350f339c87ecf98a5035eddaf28ea7
decrypt: hello123�
After padding (Null): 68656c6c6f3132330000000000000000
Cipher (ECB): 38f1e8924bd807d926e9df17ba4db72e
decrypt: hello123
After padding (Space): 68656c6c6f3132330000000000000000
Cipher (ECB): 38f1e8924bd807d926e9df17ba4db72e
decrypt:
After padding (Random): 68656c6c6f313233e5fa500d0def3f07
Cipher (ECB): 128c2ed64c7717c4adeb1833059767e2
decrypt: hello123å

PKCS (Public-Key Cryptography Standards) were designed and published, in the 1990s, by RSA Security Inc, and have now been standardised in the form of RFCs. PKCS #5 (RFC 2859) is a standard used for password-based encryption, and PKCS #7 (RFC 2815) is used to sign and/or encrypt messages for PKI.

If we use “hello” and DES we have a block size of 8 bytes (or 16 hex characters), we must pad to 5 bytes, this means there are 3 padding bytes (0x3) to give [here]:

After padding (CMS): 68656c6c6f030303
Cipher (ECB): 8f770898ddb9fb38
decrypt: hello

If we use “hello1”, then we must pad to 6 bytes, this means there are 2 padding bytes (0x2) to give:

After padding (CMS): 68656c6c6f310202
Cipher (ECB): 602743be4d9c6f17
decrypt: hello1

The following code generates the 256-bit AES key from a SHA-256 hash of the password:

from Crypto.Cipher import AES
import hashlib
import sys
import binascii
import Padding
val='hello'
password='hello'
plaintext=val
def encrypt(plaintext,key, mode):
encobj = AES.new(key,mode)
return(encobj.encrypt(plaintext))
def decrypt(ciphertext,key, mode):
encobj = AES.new(key,mode)
return(encobj.decrypt(ciphertext))
key = hashlib.sha256(password).digest()

plaintext = Padding.appendPadding(plaintext,blocksize=Padding.AES_blocksize,mode='CMS')
print "After padding (CMS): "+binascii.hexlify(bytearray(plaintext))
ciphertext = encrypt(plaintext,key,AES.MODE_ECB)
print "Cipher (ECB): "+binascii.hexlify(bytearray(ciphertext))
plaintext = decrypt(ciphertext,key,AES.MODE_ECB)
plaintext = Padding.removePadding(plaintext,mode='CMS')
print " decrypt: "+plaintext

plaintext=val

plaintext = Padding.appendPadding(plaintext,blocksize=Padding.AES_blocksize,mode='ZeroLen')
print "\nAfter padding (Bit): "+binascii.hexlify(bytearray(plaintext))
ciphertext = encrypt(plaintext,key,AES.MODE_ECB)
print "Cipher (ECB): "+binascii.hexlify(bytearray(ciphertext))
plaintext = decrypt(ciphertext,key,AES.MODE_ECB)
plaintext = Padding.removePadding(plaintext,blocksize=Padding.AES_blocksize,mode='ZeroLen')
print " decrypt: "+plaintext

plaintext=val
plaintext = Padding.appendPadding(plaintext,blocksize=Padding.AES_blocksize,mode='Space')
print "\nAfter padding (Null): "+binascii.hexlify(bytearray(plaintext))
ciphertext = encrypt(plaintext,key,AES.MODE_ECB)
print "Cipher (ECB): "+binascii.hexlify(bytearray(ciphertext))
plaintext = decrypt(ciphertext,key,AES.MODE_ECB)
plaintext = Padding.removePadding(plaintext,blocksize=Padding.AES_blocksize,mode='Space')
print " decrypt: "+plaintext

plaintext=val
plaintext = Padding.appendPadding(plaintext,blocksize=Padding.AES_blocksize,mode='Random')
print "\nAfter padding (Random): "+binascii.hexlify(bytearray(plaintext))
ciphertext = encrypt(plaintext,key,AES.MODE_ECB)
print "Cipher (ECB): "+binascii.hexlify(bytearray(ciphertext))
plaintext = decrypt(ciphertext,key,AES.MODE_ECB)
plaintext = Padding.removePadding(plaintext,mode='Random')
print " decrypt: "+plaintext

Conclusions

Padding keeps us all straight when we decrypt our data. If you ever get strange characters at the end of your message, it might be that your padding is not quite working right.

Just imagine you created the most amazing machine in the world. Many people would want to see inside it, and understand how it works. Well AES is pretty much one of the most amazing things that has ever been created for the protection of our citizens, but not many people actually know how it works. So go and learn how this fantastic machine works.

While public key encryption is a preening peacock, AES is the true the workhorse of our industry. Together they have produced the most amazing machine we have ever created.

Here are the links:

  • Padding (AES). Padding. This outlines how data is padded for AES.
  • Padding (DES). Padding. This outlines how data is padded for DES.
  • Padding (DES) with CBC. Padding. This outlines how data is padded for DES for CBC.