Padding In Aes Algorithm
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'