July 30, 2019

# Cryptopals Challenges: #9

In this challenge we implement a padding scheme for usage in later cryptography problems. Beginning Set 2 we are asked to implement PKCS#7 padding.  To do this, we pass a string and blocksize to the padding function.  If the string is not evenly divisible by the blocksize by n bytes, we append n bytes of "\x0n".  For example, if we had a string that was 4 bytes short, we would append 4 bytes of "\x04".

Since we are implementing padding, it is also smart to implement a unpad function.  Also, since we are using Python we can throw errors if the padding is incorrect when trying to unpad.  Implementing the padding function is simple using Python's byte manipulation syntax.  We compute the number of bytes needed by subtracting the length of the text (mod blocksize) from the blocksize.  We then add this to the text concatenating and using the multiplication operator on the bytes.

def pad_pkcs7(text, blocksize):

#Compute the number of padding bytes needed.
padding = blocksize - len(text) % blocksize

#Add that many bytes
text += bytes(chr(padding),'utf-8')*padding

return text

To implement an unpadding method, we first have to check if the string is the correct blocksize.  If text (mod blocksize) is not zero, then the text is not evenly divisible by the blocksize and the padding was incorrect.  We then take the last bit of the string using Python's handy array indexing which loops around the text (text[-1] gives the last byte).  If the text does not end with a string of n bytes of the last byte, we throw an error.

def unpad_pkcs7(text, blocksize):

#Padding should produce a string divisible by 16
if len(text) % blocksize != 0:
raise IncorrectPadding

#Check if the string ends with n amounts of the last byte
last_byte = text[-1]
if text.endswith(bytes([last_byte])*last_byte):
#Return up to the last "last_byte" characters
return text[:-last_byte]
else:
raise IncorrectPadding

That's it for implementing PKCS#7 padding.  Next time we work on a more challenging problem of implementing CBC mode for AES.