Question

I use a Padding function:

def _pad(self, s):
    return s + (self.bs - len(s) % self.bs) * chr(self.bs - len(s) % self.bs)

def _unpad(self, s):
    return s[:-ord(s[len(s)-1:])]

Due to a certain lack of syntax and modulo skills here, I don't see through this. Is this bet practice for padding and unpadding messages for AES CBC en/decryption? Or would you recommend a different function?

self.bs is the blocksize, which is 32 by default.

Was it helpful?

Solution

The tricky part of the functions you show is that they encode the amount of padding being applied in the ASCII value of the padding character using chr and ord to encode and decode the value, respectively. That's pretty clever. It does require that all strings be padded though, even ones who's lengths were already exact multiples of self.bs.

Here's a clearer version of the two functions, which has the different steps explicitly split out:

def _pad(self, s):
    amount_of_padding = self.bs - len(s) % self.bs   # between 1 and self.bs, inclusive
    padding_char = chr(amount_of_padding)            # encode amount_of_padding in ASCII!
    return s + amount_of_padding * padding_char      # do string repetition with *

def _unpad(self, s):
    padding_char = s[-1]                     # last char is always part of the padding
    amount_of_padding = ord(padding_char)    # decode amount from ASCII value of char
    return s[:-amount_of_padding]            # slice to skip padding chars

The only odd thing in the original code is in _unpad where they use of s[len(s)-1] rather than s[-1]. I don't see any reason for that, since the two expressions do exactly the same thing (get the last character).

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top