From 05e8866737e23eb1075f84c029629c7e01414e9e Mon Sep 17 00:00:00 2001 From: ThunderEX Date: Wed, 3 May 2017 13:15:26 +0800 Subject: [PATCH 1/4] rm depend on copy, correct imports --- pyaes/aes.py | 7 +++---- pyaes/blockfeeder.py | 4 ++-- pyaes/util.py | 2 +- tests/test-aes.py | 6 ++---- tests/test-blockfeeder.py | 18 ++++++++---------- tests/test-util.py | 8 +++----- 6 files changed, 19 insertions(+), 26 deletions(-) diff --git a/pyaes/aes.py b/pyaes/aes.py index c6e8bc0..12dcd46 100644 --- a/pyaes/aes.py +++ b/pyaes/aes.py @@ -51,7 +51,6 @@ # See the README.md for API details and general information. -import copy import struct __all__ = ["AES", "AESModeOfOperationCTR", "AESModeOfOperationCBC", "AESModeOfOperationCFB", @@ -74,7 +73,7 @@ def _concat_list(a, b): # Python 3 compatibility try: xrange -except Exception: +except NameError: xrange = range # Python 3 supports bytes, which is already an array of integers @@ -221,7 +220,7 @@ def encrypt(self, plaintext): self.T3[(t[(i + s2) % 4] >> 8) & 0xFF] ^ self.T4[ t[(i + s3) % 4] & 0xFF] ^ self._Ke[r][i]) - t = copy.copy(a) + t = a[:] # The last round is special result = [ ] @@ -255,7 +254,7 @@ def decrypt(self, ciphertext): self.T7[(t[(i + s2) % 4] >> 8) & 0xFF] ^ self.T8[ t[(i + s3) % 4] & 0xFF] ^ self._Kd[r][i]) - t = copy.copy(a) + t = a[:] # The last round is special result = [ ] diff --git a/pyaes/blockfeeder.py b/pyaes/blockfeeder.py index f4113c3..88c8287 100644 --- a/pyaes/blockfeeder.py +++ b/pyaes/blockfeeder.py @@ -21,8 +21,8 @@ # THE SOFTWARE. -from .aes import AESBlockModeOfOperation, AESSegmentModeOfOperation, AESStreamModeOfOperation -from .util import append_PKCS7_padding, strip_PKCS7_padding, to_bufferable +from pyaes.aes import AESBlockModeOfOperation, AESSegmentModeOfOperation, AESStreamModeOfOperation +from pyaes.util import append_PKCS7_padding, strip_PKCS7_padding, to_bufferable # First we inject three functions to each of the modes of operations diff --git a/pyaes/util.py b/pyaes/util.py index 081a375..daf6ad8 100644 --- a/pyaes/util.py +++ b/pyaes/util.py @@ -34,7 +34,7 @@ def _get_byte(c): try: xrange -except: +except NameError: def to_bufferable(binary): if isinstance(binary, bytes): diff --git a/tests/test-aes.py b/tests/test-aes.py index afa59aa..2d92a72 100644 --- a/tests/test-aes.py +++ b/tests/test-aes.py @@ -22,7 +22,7 @@ import sys -sys.path.append('../pyaes') +sys.path.append('..') from pyaes import * @@ -33,8 +33,6 @@ xrange except NameError: xrange = range -else: - pass # compare against a known working implementation from Crypto.Cipher import AES as KAES @@ -141,7 +139,7 @@ tt_kdecrypt += time.time() - t0 t0 = time.time() - dt2 = [aes2.decrypt(k) for k in kenc] + dt2 = [aes2.decrypt(k) for k in enc] tt_decrypt += time.time() - t0 if plaintext != dt2: diff --git a/tests/test-blockfeeder.py b/tests/test-blockfeeder.py index 41bd487..31af4e8 100644 --- a/tests/test-blockfeeder.py +++ b/tests/test-blockfeeder.py @@ -22,20 +22,18 @@ import sys -sys.path.append('../pyaes') +sys.path.append('..') import os import random try: - from StringIO import StringIO -except: - import io - StringIO = io.BytesIO + from StringIO import StringIO as BytesIO +except ImportError: + from io import BytesIO import pyaes from pyaes.blockfeeder import Decrypter, Encrypter -from pyaes import decrypt_stream, encrypt_stream from pyaes.util import to_bufferable @@ -132,14 +130,14 @@ kw['iv'] = os.urandom(16) moo = mode(**kw) - output = StringIO() - pyaes.encrypt_stream(moo, StringIO(plaintext), output) + output = BytesIO() + pyaes.encrypt_stream(moo, BytesIO(plaintext), output) output.seek(0) ciphertext = output.read() moo = mode(**kw) - output = StringIO() - pyaes.decrypt_stream(moo, StringIO(ciphertext), output) + output = BytesIO() + pyaes.decrypt_stream(moo, BytesIO(ciphertext), output) output.seek(0) decrypted = output.read() diff --git a/tests/test-util.py b/tests/test-util.py index db30918..a284a7b 100644 --- a/tests/test-util.py +++ b/tests/test-util.py @@ -22,19 +22,17 @@ import sys -sys.path.append('../pyaes') +sys.path.append('..') from pyaes.util import append_PKCS7_padding, strip_PKCS7_padding -byte = 'A' +byte = b'A' # Python 3 compatibility try: xrange -except Exception: +except NameError: xrange = range - # convert sample byte to bytes type, so that data = byte * i yields bytes, not str - byte = bytes(byte, 'utf-8') for i in xrange(0, 17): data = byte * i From 949d556cead3e8b42cd8d46edf5321245f257df7 Mon Sep 17 00:00:00 2001 From: ThunderEX Date: Wed, 3 May 2017 14:21:29 +0800 Subject: [PATCH 2/4] rm ugly workaround for py2/3, replace with bytes/bytearray --- pyaes/aes.py | 65 +++++++++++++-------------------------- pyaes/blockfeeder.py | 16 +++++----- pyaes/util.py | 21 ++----------- tests/test-blockfeeder.py | 9 +++--- 4 files changed, 35 insertions(+), 76 deletions(-) diff --git a/pyaes/aes.py b/pyaes/aes.py index 12dcd46..76e9e4f 100644 --- a/pyaes/aes.py +++ b/pyaes/aes.py @@ -60,15 +60,6 @@ def _compact_word(word): return (word[0] << 24) | (word[1] << 16) | (word[2] << 8) | word[3] -def _string_to_bytes(text): - return list(ord(c) for c in text) - -def _bytes_to_string(binary): - return "".join(chr(b) for b in binary) - -def _concat_list(a, b): - return a + b - # Python 3 compatibility try: @@ -76,20 +67,6 @@ def _concat_list(a, b): except NameError: xrange = range - # Python 3 supports bytes, which is already an array of integers - def _string_to_bytes(text): - if isinstance(text, bytes): - return text - return [ord(c) for c in text] - - # In Python 3, we return bytes - def _bytes_to_string(binary): - return bytes(binary) - - # Python 3 cannot concatenate a list onto a bytes, so we bytes-ify it first - def _concat_list(a, b): - return a + bytes(b) - # Based *largely* on the Rijndael implementation # See: http://csrc.nist.gov/publications/fips/fips197/fips-197.pdf @@ -340,15 +317,15 @@ def encrypt(self, plaintext): if len(plaintext) != 16: raise ValueError('plaintext block must be 16 bytes') - plaintext = _string_to_bytes(plaintext) - return _bytes_to_string(self._aes.encrypt(plaintext)) + plaintext = bytearray(plaintext) + return bytes(self._aes.encrypt(plaintext)) def decrypt(self, ciphertext): if len(ciphertext) != 16: raise ValueError('ciphertext block must be 16 bytes') - ciphertext = _string_to_bytes(ciphertext) - return _bytes_to_string(self._aes.decrypt(ciphertext)) + ciphertext = bytearray(ciphertext) + return bytes(self._aes.decrypt(ciphertext)) @@ -379,7 +356,7 @@ def __init__(self, key, iv = None): elif len(iv) != 16: raise ValueError('initialization vector must be 16 bytes') else: - self._last_cipherblock = _string_to_bytes(iv) + self._last_cipherblock = bytearray(iv) AESBlockModeOfOperation.__init__(self, key) @@ -387,21 +364,21 @@ def encrypt(self, plaintext): if len(plaintext) != 16: raise ValueError('plaintext block must be 16 bytes') - plaintext = _string_to_bytes(plaintext) + plaintext = bytearray(plaintext) precipherblock = [ (p ^ l) for (p, l) in zip(plaintext, self._last_cipherblock) ] self._last_cipherblock = self._aes.encrypt(precipherblock) - return _bytes_to_string(self._last_cipherblock) + return bytes(self._last_cipherblock) def decrypt(self, ciphertext): if len(ciphertext) != 16: raise ValueError('ciphertext block must be 16 bytes') - cipherblock = _string_to_bytes(ciphertext) + cipherblock = bytearray(ciphertext) plaintext = [ (p ^ l) for (p, l) in zip(self._aes.decrypt(cipherblock), self._last_cipherblock) ] self._last_cipherblock = cipherblock - return _bytes_to_string(plaintext) + return bytes(plaintext) @@ -426,7 +403,7 @@ def __init__(self, key, iv, segment_size = 1): elif len(iv) != 16: raise ValueError('initialization vector must be 16 bytes') else: - self._shift_register = _string_to_bytes(iv) + self._shift_register = bytearray(iv) self._segment_bytes = segment_size @@ -438,7 +415,7 @@ def encrypt(self, plaintext): if len(plaintext) % self._segment_bytes != 0: raise ValueError('plaintext block must be a multiple of segment_size') - plaintext = _string_to_bytes(plaintext) + plaintext = bytearray(plaintext) # Break block into segments encrypted = [ ] @@ -448,17 +425,17 @@ def encrypt(self, plaintext): cipher_segment = [ (p ^ x) for (p, x) in zip(plaintext_segment, xor_segment) ] # Shift the top bits out and the ciphertext in - self._shift_register = _concat_list(self._shift_register[len(cipher_segment):], cipher_segment) + self._shift_register = self._shift_register[len(cipher_segment):] + bytes(cipher_segment) encrypted.extend(cipher_segment) - return _bytes_to_string(encrypted) + return bytes(encrypted) def decrypt(self, ciphertext): if len(ciphertext) % self._segment_bytes != 0: raise ValueError('ciphertext block must be a multiple of segment_size') - ciphertext = _string_to_bytes(ciphertext) + ciphertext = bytearray(ciphertext) # Break block into segments decrypted = [ ] @@ -468,11 +445,11 @@ def decrypt(self, ciphertext): plaintext_segment = [ (p ^ x) for (p, x) in zip(cipher_segment, xor_segment) ] # Shift the top bits out and the ciphertext in - self._shift_register = _concat_list(self._shift_register[len(cipher_segment):], cipher_segment) + self._shift_register = self._shift_register[len(cipher_segment):] + bytes(cipher_segment) decrypted.extend(plaintext_segment) - return _bytes_to_string(decrypted) + return bytes(decrypted) @@ -498,7 +475,7 @@ def __init__(self, key, iv = None): elif len(iv) != 16: raise ValueError('initialization vector must be 16 bytes') else: - self._last_precipherblock = _string_to_bytes(iv) + self._last_precipherblock = bytearray(iv) self._remaining_block = [ ] @@ -506,7 +483,7 @@ def __init__(self, key, iv = None): def encrypt(self, plaintext): encrypted = [ ] - for p in _string_to_bytes(plaintext): + for p in bytearray(plaintext): if len(self._remaining_block) == 0: self._remaining_block = self._aes.encrypt(self._last_precipherblock) self._last_precipherblock = [ ] @@ -515,7 +492,7 @@ def encrypt(self, plaintext): cipherbyte = p ^ precipherbyte encrypted.append(cipherbyte) - return _bytes_to_string(encrypted) + return bytes(encrypted) def decrypt(self, ciphertext): # AES-OFB is symetric @@ -566,12 +543,12 @@ def encrypt(self, plaintext): self._remaining_counter += self._aes.encrypt(self._counter.value) self._counter.increment() - plaintext = _string_to_bytes(plaintext) + plaintext = bytearray(plaintext) encrypted = [ (p ^ c) for (p, c) in zip(plaintext, self._remaining_counter) ] self._remaining_counter = self._remaining_counter[len(encrypted):] - return _bytes_to_string(encrypted) + return bytes(encrypted) def decrypt(self, crypttext): # AES-CTR is symetric diff --git a/pyaes/blockfeeder.py b/pyaes/blockfeeder.py index 88c8287..e1b5bfb 100644 --- a/pyaes/blockfeeder.py +++ b/pyaes/blockfeeder.py @@ -22,7 +22,7 @@ from pyaes.aes import AESBlockModeOfOperation, AESSegmentModeOfOperation, AESStreamModeOfOperation -from pyaes.util import append_PKCS7_padding, strip_PKCS7_padding, to_bufferable +from pyaes.util import append_PKCS7_padding, strip_PKCS7_padding # First we inject three functions to each of the modes of operations @@ -99,8 +99,8 @@ def _segment_final_encrypt(self, data, padding = PADDING_DEFAULT): if padding != PADDING_DEFAULT: raise Exception('invalid padding option') - faux_padding = (chr(0) * (self.segment_bytes - (len(data) % self.segment_bytes))) - padded = data + to_bufferable(faux_padding) + faux_padding = (b'\x00' * (self.segment_bytes - (len(data) % self.segment_bytes))) + padded = data + bytes(faux_padding) return self.encrypt(padded)[:len(data)] # CFB can handle a non-segment-sized block at the end using the remaining cipherblock @@ -108,8 +108,8 @@ def _segment_final_decrypt(self, data, padding = PADDING_DEFAULT): if padding != PADDING_DEFAULT: raise Exception('invalid padding option') - faux_padding = (chr(0) * (self.segment_bytes - (len(data) % self.segment_bytes))) - padded = data + to_bufferable(faux_padding) + faux_padding = (b'\x00' * (self.segment_bytes - (len(data) % self.segment_bytes))) + padded = data + bytes(faux_padding) return self.decrypt(padded)[:len(data)] AESSegmentModeOfOperation._can_consume = _segment_can_consume @@ -150,7 +150,7 @@ def __init__(self, mode, feed, final, padding = PADDING_DEFAULT): self._mode = mode self._feed = feed self._final = final - self._buffer = to_bufferable("") + self._buffer = b"" self._padding = padding def feed(self, data = None): @@ -170,10 +170,10 @@ def feed(self, data = None): self._buffer = None return result - self._buffer += to_bufferable(data) + self._buffer += bytes(data) # We keep 16 bytes around so we can determine padding - result = to_bufferable('') + result = b'' while len(self._buffer) > 16: can_consume = self._mode._can_consume(len(self._buffer) - 16) if can_consume == 0: break diff --git a/pyaes/util.py b/pyaes/util.py index daf6ad8..e6dd22d 100644 --- a/pyaes/util.py +++ b/pyaes/util.py @@ -26,33 +26,16 @@ # represent arbitrary binary data, we must use the "bytes" object. This method # ensures the object behaves as we need it to. -def to_bufferable(binary): - return binary - -def _get_byte(c): - return ord(c) - -try: - xrange -except NameError: - - def to_bufferable(binary): - if isinstance(binary, bytes): - return binary - return bytes(ord(b) for b in binary) - - def _get_byte(c): - return c def append_PKCS7_padding(data): pad = 16 - (len(data) % 16) - return data + to_bufferable(chr(pad) * pad) + return data + bytes([pad]) * pad def strip_PKCS7_padding(data): if len(data) % 16 != 0: raise ValueError("invalid length") - pad = _get_byte(data[-1]) + pad = bytearray(data)[-1] if pad > 16: raise ValueError("invalid padding byte") diff --git a/tests/test-blockfeeder.py b/tests/test-blockfeeder.py index 31af4e8..ed66f8a 100644 --- a/tests/test-blockfeeder.py +++ b/tests/test-blockfeeder.py @@ -34,7 +34,6 @@ import pyaes from pyaes.blockfeeder import Decrypter, Encrypter -from pyaes.util import to_bufferable key = os.urandom(32) @@ -50,7 +49,7 @@ kw['iv'] = os.urandom(16) encrypter = Encrypter(mode(**kw)) - ciphertext = to_bufferable('') + ciphertext = b'' # Feed the encrypter random number of bytes at a time index = 0 @@ -62,7 +61,7 @@ ciphertext += encrypter.feed(None) decrypter = Decrypter(mode(**kw)) - decrypted = to_bufferable('') + decrypted = b'' # Feed the decrypter random number of bytes at a time index = 0 @@ -89,7 +88,7 @@ kw['iv'] = os.urandom(16) encrypter = Encrypter(mode(**kw), padding = pyaes.PADDING_NONE) - ciphertext = to_bufferable('') + ciphertext = b'' # Feed the encrypter random number of bytes at a time index = 0 @@ -104,7 +103,7 @@ print(' failed to encrypt with correct padding') decrypter = Decrypter(mode(**kw), padding = pyaes.PADDING_NONE) - decrypted = to_bufferable('') + decrypted = b'' # Feed the decrypter random number of bytes at a time index = 0 From 738c633ec5216a532ca3ffed3074459177376d50 Mon Sep 17 00:00:00 2001 From: ThunderEX Date: Wed, 3 May 2017 16:40:19 +0800 Subject: [PATCH 3/4] don't mask MSB, increase speed a little bit --- pyaes/aes.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/pyaes/aes.py b/pyaes/aes.py index 76e9e4f..be262db 100644 --- a/pyaes/aes.py +++ b/pyaes/aes.py @@ -137,7 +137,7 @@ def __init__(self, key): tk[0] ^= ((self.S[(tt >> 16) & 0xFF] << 24) ^ (self.S[(tt >> 8) & 0xFF] << 16) ^ (self.S[ tt & 0xFF] << 8) ^ - self.S[(tt >> 24) & 0xFF] ^ + self.S[(tt >> 24) ] ^ (self.rcon[rconpointer] << 24)) rconpointer += 1 @@ -154,7 +154,7 @@ def __init__(self, key): tk[KC // 2] ^= (self.S[ tt & 0xFF] ^ (self.S[(tt >> 8) & 0xFF] << 8) ^ (self.S[(tt >> 16) & 0xFF] << 16) ^ - (self.S[(tt >> 24) & 0xFF] << 24)) + (self.S[(tt >> 24) ] << 24)) for i in xrange(KC // 2 + 1, KC): tk[i] ^= tk[i - 1] @@ -171,7 +171,7 @@ def __init__(self, key): for r in xrange(1, rounds): for j in xrange(0, 4): tt = self._Kd[r][j] - self._Kd[r][j] = (self.U1[(tt >> 24) & 0xFF] ^ + self._Kd[r][j] = (self.U1[(tt >> 24) ] ^ self.U2[(tt >> 16) & 0xFF] ^ self.U3[(tt >> 8) & 0xFF] ^ self.U4[ tt & 0xFF]) @@ -192,7 +192,7 @@ def encrypt(self, plaintext): # Apply round transforms for r in xrange(1, rounds): for i in xrange(0, 4): - a[i] = (self.T1[(t[ i ] >> 24) & 0xFF] ^ + a[i] = (self.T1[(t[ i ] >> 24) ] ^ self.T2[(t[(i + s1) % 4] >> 16) & 0xFF] ^ self.T3[(t[(i + s2) % 4] >> 8) & 0xFF] ^ self.T4[ t[(i + s3) % 4] & 0xFF] ^ @@ -203,7 +203,7 @@ def encrypt(self, plaintext): result = [ ] for i in xrange(0, 4): tt = self._Ke[rounds][i] - result.append((self.S[(t[ i ] >> 24) & 0xFF] ^ (tt >> 24)) & 0xFF) + result.append((self.S[(t[ i ] >> 24) ] ^ (tt >> 24)) & 0xFF) result.append((self.S[(t[(i + s1) % 4] >> 16) & 0xFF] ^ (tt >> 16)) & 0xFF) result.append((self.S[(t[(i + s2) % 4] >> 8) & 0xFF] ^ (tt >> 8)) & 0xFF) result.append((self.S[ t[(i + s3) % 4] & 0xFF] ^ tt ) & 0xFF) @@ -226,7 +226,7 @@ def decrypt(self, ciphertext): # Apply round transforms for r in xrange(1, rounds): for i in xrange(0, 4): - a[i] = (self.T5[(t[ i ] >> 24) & 0xFF] ^ + a[i] = (self.T5[(t[ i ] >> 24) ] ^ self.T6[(t[(i + s1) % 4] >> 16) & 0xFF] ^ self.T7[(t[(i + s2) % 4] >> 8) & 0xFF] ^ self.T8[ t[(i + s3) % 4] & 0xFF] ^ @@ -237,7 +237,7 @@ def decrypt(self, ciphertext): result = [ ] for i in xrange(0, 4): tt = self._Kd[rounds][i] - result.append((self.Si[(t[ i ] >> 24) & 0xFF] ^ (tt >> 24)) & 0xFF) + result.append((self.Si[(t[ i ] >> 24) ] ^ (tt >> 24)) & 0xFF) result.append((self.Si[(t[(i + s1) % 4] >> 16) & 0xFF] ^ (tt >> 16)) & 0xFF) result.append((self.Si[(t[(i + s2) % 4] >> 8) & 0xFF] ^ (tt >> 8)) & 0xFF) result.append((self.Si[ t[(i + s3) % 4] & 0xFF] ^ tt ) & 0xFF) From 46a62ac23c48d9adab2dddbf368f2f8720fd75b6 Mon Sep 17 00:00:00 2001 From: ThunderEX Date: Wed, 17 May 2017 16:49:41 +0800 Subject: [PATCH 4/4] fix broken py2 --- pyaes/aes.py | 20 ++++++++++---------- pyaes/util.py | 2 +- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/pyaes/aes.py b/pyaes/aes.py index be262db..24ea793 100644 --- a/pyaes/aes.py +++ b/pyaes/aes.py @@ -318,14 +318,14 @@ def encrypt(self, plaintext): raise ValueError('plaintext block must be 16 bytes') plaintext = bytearray(plaintext) - return bytes(self._aes.encrypt(plaintext)) + return bytes(bytearray(self._aes.encrypt(plaintext))) def decrypt(self, ciphertext): if len(ciphertext) != 16: raise ValueError('ciphertext block must be 16 bytes') ciphertext = bytearray(ciphertext) - return bytes(self._aes.decrypt(ciphertext)) + return bytes(bytearray(self._aes.decrypt(ciphertext))) @@ -368,7 +368,7 @@ def encrypt(self, plaintext): precipherblock = [ (p ^ l) for (p, l) in zip(plaintext, self._last_cipherblock) ] self._last_cipherblock = self._aes.encrypt(precipherblock) - return bytes(self._last_cipherblock) + return bytes(bytearray(self._last_cipherblock)) def decrypt(self, ciphertext): if len(ciphertext) != 16: @@ -378,7 +378,7 @@ def decrypt(self, ciphertext): plaintext = [ (p ^ l) for (p, l) in zip(self._aes.decrypt(cipherblock), self._last_cipherblock) ] self._last_cipherblock = cipherblock - return bytes(plaintext) + return bytes(bytearray(plaintext)) @@ -425,11 +425,11 @@ def encrypt(self, plaintext): cipher_segment = [ (p ^ x) for (p, x) in zip(plaintext_segment, xor_segment) ] # Shift the top bits out and the ciphertext in - self._shift_register = self._shift_register[len(cipher_segment):] + bytes(cipher_segment) + self._shift_register = self._shift_register[len(cipher_segment):] + bytearray(cipher_segment) encrypted.extend(cipher_segment) - return bytes(encrypted) + return bytes(bytearray(encrypted)) def decrypt(self, ciphertext): if len(ciphertext) % self._segment_bytes != 0: @@ -445,11 +445,11 @@ def decrypt(self, ciphertext): plaintext_segment = [ (p ^ x) for (p, x) in zip(cipher_segment, xor_segment) ] # Shift the top bits out and the ciphertext in - self._shift_register = self._shift_register[len(cipher_segment):] + bytes(cipher_segment) + self._shift_register = self._shift_register[len(cipher_segment):] + bytearray(cipher_segment) decrypted.extend(plaintext_segment) - return bytes(decrypted) + return bytes(bytearray(decrypted)) @@ -492,7 +492,7 @@ def encrypt(self, plaintext): cipherbyte = p ^ precipherbyte encrypted.append(cipherbyte) - return bytes(encrypted) + return bytes(bytearray(encrypted)) def decrypt(self, ciphertext): # AES-OFB is symetric @@ -548,7 +548,7 @@ def encrypt(self, plaintext): encrypted = [ (p ^ c) for (p, c) in zip(plaintext, self._remaining_counter) ] self._remaining_counter = self._remaining_counter[len(encrypted):] - return bytes(encrypted) + return bytes(bytearray(encrypted)) def decrypt(self, crypttext): # AES-CTR is symetric diff --git a/pyaes/util.py b/pyaes/util.py index e6dd22d..751f14b 100644 --- a/pyaes/util.py +++ b/pyaes/util.py @@ -29,7 +29,7 @@ def append_PKCS7_padding(data): pad = 16 - (len(data) % 16) - return data + bytes([pad]) * pad + return data + bytes(bytearray([pad])) * pad def strip_PKCS7_padding(data): if len(data) % 16 != 0: