Padding In Aes Algorithm

·

2 min read

WHY WE NEED PADDING

as aes algo works with fixed size of block , input string which is not multiple of block size can give you error.

for eg

  • block size of 5
  • input1 = '12345' -> valid
  • input2 = '1234567890' -> invalid
  • input3 = '1234' -> valid

HOW TO DO PADDING

Let us say we need to pad input "YELLOW SUBMARINE" and with block size of 20

so from above we can see that 16 (size of input) is not multiple of 20,so we need to add something to 16 so that it becomes multiple of 20

padding = block_size-(len(plaintext)%block_size)

you need more 4 bytes so 4 = 20 - (16%20)

HOW TO CHECK WHETHER INPUT IS PADDED OR NOT

You can check this by seeing whether given unpadding string length is multiple of blocksize.

if(len(padded)%block_size):
        raise ValueError("Input data is not padded")

HOW TO KNOW WHETHER PADDING DONE IS VALID PADDING

extract the last byte of padded input then make temporary padded bytes from it and compare it with last padded section with input

pad = padded[-1]
return padded[-pad:] == bytes([pad])*pad

HOW TO UNPAD GIVEN PADDED INPUT first check whether it is padded or not. then check whether has valid padding or not then unpad it

# if length of s1 & s2 are not equivalent then input is not padded 
    if(len(padded)%block_size):
        raise ValueError("Input data is not padded")

    # and if there is  padding check whether is it valid or not
    if not is_valid_padding(padded):
        raise ValueError("Not valid padding")

    return padded[:-padded[-1]]

FINAL CODE

from pydoc import plain

# function for performing padding
def pad(plaintext: bytes,block_size :int) -> bytes:

    # extra padding to be done
    padding = block_size-(len(plaintext)%block_size)

    # return the padded string
    return plaintext+bytes([padding]*padding)

# check for valid padding
def is_valid_padding(padded: bytes) -> bool:
    pad = padded[-1]
    return padded[-pad:] == bytes([pad])*pad

# function to unpad given padded input
def unpad(padded:bytes,block_size:int)->bytes:

    # if length of s1 & s2 are not equivalent then input is not padded 
    if(len(padded)%block_size):
        raise ValueError("Input data is not padded")

    # and if there is  padding check whether is it valid or not
    if not is_valid_padding(padded):
        raise ValueError("Not valid padding")

    return padded[:-padded[-1]]

print(pad(b"YELLOW SUBMARINE",20))
# output => b'YELLOW SUBMARINE\x04\x04\x04\x04'

print(unpad(b'YELLOW SUBMARINE\x04\x04\x04\x04',20))
# output => b'YELLOW SUBMARINE'