def test_padding_size(): i = 13 bs = 16 r = padding_size(i, bs) assert r == bs i = 16 bs = 16 r = padding_size(i, bs) assert r == bs i = 13 bs = 16 r = padding_size(i, bs, ceil=False) assert r == 0
def _read_block(self, size: int = -1): """Read encrypted block to cache""" data = self._io.read(size) if not data: return self._encrypted_io_offset += len(data) self._encrypted_cache.extend(data) avail_enc_len = padding_size(len(self._encrypted_cache), self.BLOCK_SIZE, ceil=False) if avail_enc_len > 0: enc_cn = self._encrypted_cache[:avail_enc_len] self._encrypted_cache = self._encrypted_cache[avail_enc_len:] else: enc_cn = b"" # The end decryption if self._encrypted_io_offset == self._encrypted_io_len: if self._encrypted_cache: enc_cn += bytes(self._encrypted_cache) self._encrypted_cache.clear() dec_cn = self._crypto.decrypt(enc_cn) if self._encrypted_data_padded: dec_cn = pkcs7_unpadding(dec_cn, self.BLOCK_SIZE) self._crypto.finalize() else: dec_cn = self._crypto.decrypt(enc_cn) self._decrypted_cache.extend(dec_cn)
def __len__(self) -> int: """The decrypted content length of `self._io`""" avail_enc_len = padding_size(self._io_len - self._io_init_offset, self.BLOCK_SIZE, ceil=False) return avail_enc_len
def _read_block(self, size: int = -1): """Read encrypted block to cache""" # `self._encrypted_cache` has remains. if size > 0 and len(self._encrypted_cache) > size: return # `size` must be large or equal to the `size` as `size` be the times of `self.BLOCK_SIZE` if size > 0: size = padding_size(size, self.BLOCK_SIZE) data = self._io.read(size) or b"" if not data: return self._origin_io_offset += len(data) self._origin_cache.extend(data) avail_ori_len = padding_size(len(self._origin_cache), self.BLOCK_SIZE, ceil=False) if avail_ori_len > 0: ori_cn = self._origin_cache[:avail_ori_len] self._origin_cache = self._origin_cache[avail_ori_len:] else: ori_cn = b"" # The end encryption if self._origin_io_offset == self._total_origin_len: # Take all remainder if self._origin_cache: ori_cn += bytes(self._origin_cache) self._origin_cache.clear() # Padding if self._need_data_padded: ori_cn = pkcs7_padding(ori_cn, self.BLOCK_SIZE) enc_cn = self._crypto.encrypt(ori_cn) self._crypto.finalize() else: enc_cn = self._crypto.encrypt(ori_cn) self._encrypted_cache.extend(enc_cn)
def _read_block(self, size: int = -1): """Read encrypted block to cache""" # `self._decrypted_cache` has remains. if size > 0 and len(self._decrypted_cache) > size: return # `size` must be large or equal to the `size` as `size` be the times of `self.BLOCK_SIZE` if size > 0: size = padding_size(size, self.BLOCK_SIZE) data = self._io.read(size) if not data: return self._encrypted_io_offset += len(data) self._encrypted_cache.extend(data) avail_enc_len = padding_size(len(self._encrypted_cache), self.BLOCK_SIZE, ceil=False) if avail_enc_len > 0: enc_cn = self._encrypted_cache[:avail_enc_len] self._encrypted_cache = self._encrypted_cache[avail_enc_len:] else: enc_cn = b"" # The end decryption if self._encrypted_io_offset == self._encrypted_io_len: if self._encrypted_cache: enc_cn += bytes(self._encrypted_cache) self._encrypted_cache.clear() dec_cn = self._crypto.decrypt(enc_cn) if self._encrypted_data_padded: dec_cn = pkcs7_unpadding(dec_cn, self.BLOCK_SIZE) self._crypto.finalize() else: dec_cn = self._crypto.decrypt(enc_cn) self._decrypted_cache.extend(dec_cn)
def test_aes256cbcencryptio(): key = os.urandom(32) iv = os.urandom(16) buf = os.urandom(1024 * 1024 * 50) bio = io.BytesIO(buf) c = AES256CBCEncryptIO(bio, key, iv, len(buf)) assert total_len(c) == padding_size(len(buf), 16) + ENCRYPT_HEAD_LEN enc = c.read() print("enc", len(enc)) d = to_decryptio(io.BytesIO(enc), key) # assert total_len(d) == len(buf) # can be wrong dec = d.read() print("dec", len(dec)) assert buf == dec
def __init__(self, io: IO, encrypt_key: bytes, iv: bytes, total_origin_len: int): encrypt_key = padding_key(encrypt_key, self.BLOCK_SIZE * 2) iv = padding_key(iv, self.BLOCK_SIZE) super().__init__(io, encrypt_key, iv, total_origin_len) self._crypto = AES256CBCCryptography(self._encrypt_key, self._nonce_or_iv) self._encrypted_io_offset = 0 self._encrypted_io_len = padding_size(total_origin_len, self.BLOCK_SIZE) self._encrypted_data_padded = total_origin_len != self._encrypted_io_len self._encrypted_cache = bytearray() self._decrypted_cache = bytearray()
def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self._crypto = AES256CBCCryptography(self._encrypt_key, self._nonce_or_iv) # The offset of encrypted origin content self._origin_io_offset = 0 # Origin content cache self._origin_cache = bytearray() # Total length of final encrypted content self._encrypted_io_len = padding_size(self._io_len, self.BLOCK_SIZE) # Encrypted content cache self._encrypted_cache = bytearray() self._need_data_padded = self._total_origin_len != self._encrypted_io_len
def __init__(self, io: IO, encrypt_key: Any, iv: Any, total_origin_len: int): encrypt_key = padding_key(encrypt_key, self.BLOCK_SIZE * 2) iv = padding_key(iv, self.BLOCK_SIZE) super().__init__(io, encrypt_key, iv, total_origin_len) self._crypto = AES256CBCCryptography(self._encrypt_key, self._nonce_or_iv) # The offset of encrypted origin content self._origin_io_offset = 0 # Origin content cache self._origin_cache = bytearray() # Total length of final encrypted content self._encrypted_io_len = padding_size(self._io_len, self.BLOCK_SIZE) # Encrypted content cache self._encrypted_cache = bytearray() self._need_data_padded = self._total_origin_len != self._encrypted_io_len
def test_aes256cbcencryptio(): key = os.urandom(32) buf = os.urandom(1024 * 1024 * 50 + 14) bio = io.BytesIO(buf) c = AES256CBCEncryptIO(bio, key, len(buf)) assert (total_len(c) == padding_size(len(buf), 16) + PADDED_ENCRYPT_HEAD_WITH_SALT_LEN) enc = c.read() print("enc", len(enc)) dio = to_decryptio(io.BytesIO(enc), key) # assert total_len(d) == len(buf) # can be wrong dec = dio.read() print("dec", len(dec)) assert buf == dec # Encrypt # Assert length of Read(size), size > 0 buf = os.urandom(1024 * 50) bio = io.BytesIO(buf) c = AES256CBCEncryptIO(bio, key, len(buf)) length = 0 while True: d = c.read(1) if not d: break assert len(d) == 1 length += 1 assert (total_len(c) == padding_size(len(buf), 16) + PADDED_ENCRYPT_HEAD_WITH_SALT_LEN) buf = os.urandom(1024 * 50 + 14) bio = io.BytesIO(buf) c = AES256CBCEncryptIO(bio, key, len(buf)) length = 0 while True: d = c.read(1) if not d: break assert len(d) == 1 length += 1 assert (total_len(c) == padding_size(len(buf), 16) + PADDED_ENCRYPT_HEAD_WITH_SALT_LEN) # Decrypt # Assert length of Read(size), size > 0 buf = os.urandom(1024 * 50) bio = io.BytesIO(buf) c = AES256CBCEncryptIO(bio, key, len(buf)) enc = b"" while True: d = c.read(1) if not d: break enc += d dio = to_decryptio(io.BytesIO(enc), key) length = 0 while True: d = dio.read(1) if not d: break assert len(d) == 1 length += 1 assert length == len(buf) buf = os.urandom(1024 * 50 + 14) bio = io.BytesIO(buf) c = AES256CBCEncryptIO(bio, key, len(buf)) enc = b"" while True: d = c.read(1) if not d: break enc += d dio = to_decryptio(io.BytesIO(enc), key) length = 0 while True: d = dio.read(1) if not d: break assert len(d) == 1 length += 1 assert length == len(buf)
pkcs7_unpadding, generate_salt, generate_key_iv, calu_md5, calu_crc32_and_md5, ) import requests from requests import Response READ_SIZE = 1 * constant.OneK DEFAULT_MAX_CHUNK_SIZE = 10 * constant.OneM BAIDUPCS_PY_CRYPTO_MAGIC_CODE = b"\x00@@#__BAIDUPCS_PY__CRYPTO__#@@\x00\xff" ENCRYPT_HEAD_LEN = len(BAIDUPCS_PY_CRYPTO_MAGIC_CODE) + 1 + 16 + 8 PADDED_ENCRYPT_HEAD_LEN = padding_size(ENCRYPT_HEAD_LEN, 16) PADDED_ENCRYPT_HEAD_WITH_SALT_LEN = PADDED_ENCRYPT_HEAD_LEN + 8 def total_len(o: Any) -> int: """Read obj len""" if hasattr(o, "__len__"): return len(o) if hasattr(o, "seekable"): if o.seekable(): _offset = o.tell() _len = o.seek(0, 2) o.seek(_offset, 0) return _len