def decrypt(file): key = 'ay$a5%&j' IV = 'abc@9879' PBKDF2_key = '0THISISOBmodedByForlaxNIGGAs' file_content = file.read() body = re.search('"Body": "(\w+)"', file_content) if body is None:return -1 else:body = body.group(1) des_object = DES.new(key, DES.MODE_CBC, IV) array = [] for i in range(int(len(body)/2)): array.append(binascii.unhexlify(body[i*2:i*2+2])) string = base64.b64decode(b''.join(array)) b64 = des_object.decrypt(string).replace(b'\x04', b'') e2b = base64.b64decode(b64) data = re.search(b'x0;(.*?)0;x', e2b).group(1) array = base64.b64decode(data) salt = array[:32] IV = array[32:64] array2 = array[64:] bytesl = PBKDF2(PBKDF2_key,salt,32, 1000) rijndael_cbc = RijndaelCbc( key=bytesl, iv=IV, padding=ZeroPadding(32), block_size=32 ) return rijndael_cbc.decrypt(array2).decode()
def generate_callback_data( amount=100, sale_order_id=1, ref_id=1, res_code=1, res_message=1, pay_gate_trans_id=1, rrn=1, last_four_digit_of_pan=1, ): rijndael = RijndaelCbc( key=base64.b64decode(config["key"]), iv=base64.b64decode(config["iv"]), padding=Pkcs7Padding(32), block_size=32, ) data_array = [ str(amount), # Transaction amount str(sale_order_id), # Transaction Order ID str(ref_id), # Transaction ID str(res_code), # Result Code str(res_message), # Result Message str(pay_gate_trans_id), # Transaction inquiry id str(rrn), # Bank Reference ID str(last_four_digit_of_pan), # Last four digits of payer card ID ] return { "ReturningParams": base64.b64encode(rijndael.encrypt(",".join(data_array).encode())) }
def decrypt(self, encText, previouslyProcessedData=None): if previouslyProcessedData is None: l = len(self.oldDecrypt) if l % BLOCK_SIZE == 0: previouslyProcessedData = l else: previouslyProcessedData = int(BLOCK_SIZE * math.floor(l / BLOCK_SIZE)) #print previouslyProcessedData # previouslyProcessedData was passed by the parent: it means that a frame was decoded and there was some data left. This does not include the padding zeros if previouslyProcessedData % BLOCK_SIZE != 0: previouslyProcessedData = int( BLOCK_SIZE * math.ceil(previouslyProcessedData / BLOCK_SIZE)) remainingData = self.oldDecrypt[previouslyProcessedData:] if self.oldDecrypt != b'': self.decryptIV = self.oldDecrypt[ previouslyProcessedData - BLOCK_SIZE:previouslyProcessedData] self.oldDecrypt = encText # save current block toDecrypt = truncate_multiple(remainingData + encText, BLOCK_SIZE) decryptor = RijndaelCbc(self.key, self.decryptIV, padding=ZeroPadding(BLOCK_SIZE), block_size=BLOCK_SIZE) return decryptor.decrypt(toDecrypt)
def decrypt(key, block_size, cipher_message): """ AES key,iv are the same mode cbc pkcs7 :param key: :param content: :return: """ kc = key['kc'] iv = key['iv'] ciphertext = cipher_message['ciphertext'] rijndael_cbc = RijndaelCbc( key=kc, # if it is a string we can use base64.b64decode(key), iv=iv, padding=ZeroPadding(block_size), block_size=block_size ) return rijndael_cbc.decrypt(ciphertext)
def decrypt(self, encrypted_data, previously_processed_data_index=None) -> bytes: if previously_processed_data_index is None: length = len(self.old_decrypt) if length % self.BLOCK_SIZE == 0: previously_processed_data_index = length else: previously_processed_data_index = int( self.BLOCK_SIZE * math.floor(length / self.BLOCK_SIZE)) if previously_processed_data_index % self.BLOCK_SIZE != 0: previously_processed_data_index = int( self.BLOCK_SIZE * math.ceil(previously_processed_data_index / self.BLOCK_SIZE)) remaining_data = self.old_decrypt[previously_processed_data_index:] if self.old_decrypt != '': self.decrypt_init_vector = self.old_decrypt[ previously_processed_data_index - self.BLOCK_SIZE:previously_processed_data_index] self.old_decrypt = encrypted_data cbc = RijndaelCbc(key=self.key, iv=self.decrypt_init_vector, padding=ZeroPadding(self.BLOCK_SIZE), block_size=self.BLOCK_SIZE) decrypt = cbc.decrypt(encrypted_data) return decrypt
def __init__(self, config): super().__init__(config) self.rijndael = RijndaelCbc( key=base64.b64decode(config["key"]), iv=base64.b64decode(config["iv"]), padding=Pkcs7Padding(32), block_size=32, )
def encrypt(self, plainText): encryptor = RijndaelCbc(self.key, self.encryptIV, padding=ZeroPadding(BLOCK_SIZE), block_size=BLOCK_SIZE) encText = encryptor.encrypt(plainText) self.encryptIV = encText[-BLOCK_SIZE:] return encText
def encrypt(iv, key, block_size, plaintext): rijndael_cbc = RijndaelCbc( key=key, # if it is a string we can use base64.b64decode(key), iv=iv, padding=ZeroPadding(block_size), block_size=block_size) ciphertext = rijndael_cbc.encrypt(plaintext) return ciphertext
def encrypt(self, plain_data: Union[str, bytes]) -> bytes: if isinstance(plain_data, str): plain_data = bytes(plain_data, encoding="latin_1") cbc = RijndaelCbc(key=self.key, iv=self.encrypt_init_vector, padding=ZeroPadding(self.BLOCK_SIZE), block_size=self.BLOCK_SIZE) encrypted_data = cbc.encrypt(plain_data) self.encrypt_init_vector = encrypted_data[-self.BLOCK_SIZE:] return encrypted_data
def encrypt(key, block_size, plaintext): iv = key['iv'] kc = key['kc'] ki = key['ki'] rijndael_cbc = RijndaelCbc( key=ki, # if it is a string we can use base64.b64decode(key), iv=iv, padding=ZeroPadding(block_size), block_size=block_size) MAC = rijndael_cbc.encrypt(plaintext)[-block_size:] return MAC
async def from_submission(cls, base: str, iv: str, pw: str, ver: str) -> Optional['Score']: rijndael = RijndaelCbc( # much better f**k one liners key=f'osu!-scoreburgr---------{ver}', iv=b64decode(iv), padding=Pkcs7Padding(32), block_size=32) data = rijndael.decrypt(b64decode(base)).decode().split(':') self = cls() self.map = await Beatmap.from_md5(data[0]) if (u := await glob.players.get(name=data[1].rstrip())) and u.pw == pw: self.user = u
def decrypt(iv, key, block_size, ciphertext): """ AES key,iv are the same mode cbc pkcs7 :param key: :param content: :return: """ rijndael_cbc = RijndaelCbc( key=key, # if it is a string we can use base64.b64decode(key), iv=iv, padding=ZeroPadding(block_size), block_size=block_size) return rijndael_cbc.decrypt(ciphertext)
async def from_submission(cls, data_enc: str, iv: str, osu_ver: str, phash: str) -> None: """Create a score object from an osu! submission string.""" cbc = RijndaelCbc(f'osu!-scoreburgr---------{osu_ver}', iv=base64.b64decode(iv).decode('latin_1'), padding=ZeroPadding(32), block_size=32) data = cbc.decrypt( base64.b64decode(data_enc).decode('latin_1')).decode().split(':') if len(data) != 18: plog('Received an invalid score submission.', Ansi.LRED) return s = cls() if len(map_md5 := data[0]) != 32: return
def test_rijndael_cbc(self) -> None: key = "qBS8uRhEIBsr8jr8vuY9uUpGFefYRL2HSTtrKhaI1tk=" iv = "kByhT6PjYHzJzZfXvb8Aw5URMbQnk6NM+g3IV5siWD4=" rijndael_cbc = RijndaelCbc( key=base64.b64decode(key), iv=base64.b64decode(iv), padding=Pkcs7Padding(32), block_size=32, ) with open(Path(__file__).parent / "lorem_ipsum.txt", "rb") as f: plain_text = f.read() TIMES = 100 start_time = time.perf_counter() for _ in range(TIMES): cipher = rijndael_cbc.encrypt(plain_text) plain_text = rijndael_cbc.decrypt(cipher) end_time = time.perf_counter() print(f"\n{TIMES} encryptions in {end_time - start_time:.2f} seconds")
async def from_submission(cls, data_b64: str, iv_b64: str, osu_ver: str, pw_md5: str) -> Optional['Score']: """Create a score object from an osu! submission string.""" iv = b64decode(iv_b64).decode('latin_1') data_aes = b64decode(data_b64).decode('latin_1') aes_key = f'osu!-scoreburgr---------{osu_ver}' aes = RijndaelCbc(aes_key, iv, ZeroPadding(32), 32) # score data is delimited by colons (:). data = aes.decrypt(data_aes).decode().split(':') if len(data) != 18: log('Received an invalid score submission.', Ansi.LRED) return s = cls() if len(map_md5 := data[0]) != 32: return
def decrypt(file): file_content = file.read() body = re.search('"Body": "(\w+)"', file_content) if body is None: try: e2b = base64.b64decode(file_content) data = re.search(b'0x;(.*?)x;0', e2b).group(1) array = base64.b64decode(data) salt, IV, array2 = getKeys(array) bytesl = PBKDF2(NEW_PBKDF2_key, salt, 32, 1000) rijndael_cbc = RijndaelCbc(key=bytesl, iv=IV, padding=ZeroPadding(32), block_size=32) return rijndael_cbc.decrypt(array2).decode() except binascii.Error: return -1 else: body = body.group(1) des_object = DES.new(static_key, DES.MODE_CBC, static_IV) array = [] for i in range(int(len(body) / 2)): array.append(binascii.unhexlify(body[i * 2:i * 2 + 2])) string = base64.b64decode(b''.join(array)) b64 = des_object.decrypt(string).replace(b'\x04', b'') e2b = base64.b64decode(b64) data = re.search(b'x0;(.*?)0;x', e2b).group(1) array = base64.b64decode(data) salt, IV, array2 = getKeys(array) bytesl = PBKDF2(OLD_PBKDF2_key, salt, 32, 1000) rijndael_cbc = RijndaelCbc(key=bytesl, iv=IV, padding=ZeroPadding(32), block_size=32) return rijndael_cbc.decrypt(array2).decode()
def test_rijndael_cbc(self): key = 'qBS8uRhEIBsr8jr8vuY9uUpGFefYRL2HSTtrKhaI1tk=' iv = 'kByhT6PjYHzJzZfXvb8Aw5URMbQnk6NM+g3IV5siWD4=' rijndael_cbc = RijndaelCbc(key=base64.b64decode(key), iv=base64.b64decode(iv), padding=ZeroPadding(32), block_size=32) plain_text = b'Mahdi' padded_text = plain_text.ljust(32, b'\x1b') cipher = rijndael_cbc.encrypt(padded_text) cipher_text = base64.b64encode(cipher) self.assertEqual(cipher_text, b'1KGc0PMt52Xbell+2y9qDJJp/Yy6b1JR1JWI3f9ALF4=') self.assertEqual(rijndael_cbc.decrypt(cipher), padded_text) # Long blocks plain_text = b'lorem' * 50 padded_text = plain_text.ljust(32, b'\x1b') cipher = rijndael_cbc.encrypt(padded_text) self.assertEqual(rijndael_cbc.decrypt(cipher), padded_text)
async def from_submission(cls, data_b64: str, iv_b64: str, osu_ver: str, pw_md5: str) -> Optional['Score']: """Create a score object from an osu! submission string.""" aes = RijndaelCbc(key=f'osu!-scoreburgr---------{osu_ver}', iv=b64decode(iv_b64), padding=Pkcs7Padding(32), block_size=32) # score data is delimited by colons (:). data = aes.decrypt(b64decode(data_b64)).decode().split(':') if len(data) != 18: log('Received an invalid score submission.', Ansi.LRED) return s = cls() if len(data[0]) != 32 or len(data[2]) != 32: return map_md5 = data[0] pname = data[1].rstrip() # rstrip 1 space if client has supporter s.online_checksum = data[2] # get the map & player for the score. s.bmap = await Beatmap.from_md5(map_md5) s.player = await glob.players.get_login(pname, pw_md5) if not s.player: # return the obj with an empty player to # determine whether the score failed to # be parsed vs. the user could not be found # logged in (we want to not send a reply to # the osu! client if they're simply not logged # in, so that it will retry once they login). return s # XXX: unused idx 2: online score checksum # perhaps will use to improve security at some point? # ensure all ints are safe to cast. if not all(map(str.isdecimal, data[3:11] + [data[13], data[15]])): log('Invalid parameter passed into submit-modular.', Ansi.LRED) return (s.n300, s.n100, s.n50, s.ngeki, s.nkatu, s.nmiss, s.score, s.max_combo) = map(int, data[3:11]) s.perfect = data[11] == 'True' _grade = data[12] # letter grade s.mods = Mods(int(data[13])) s.passed = data[14] == 'True' s.mode = GameMode.from_params(int(data[15]), s.mods) s.play_time = datetime.now() # TODO: use data[16] s.client_flags = ClientFlags(data[17].count(' ') & ~4) s.grade = Grade.from_str(_grade) if s.passed else Grade.F # all data read from submission. # now we can calculate things based on our data. s.calc_accuracy() if s.bmap: osu_file_path = BEATMAPS_PATH / f'{s.bmap.id}.osu' if await ensure_local_osu_file(osu_file_path, s.bmap.id, s.bmap.md5): s.pp, s.sr = s.calc_diff(osu_file_path) if s.passed: await s.calc_status() if s.bmap.status != RankedStatus.Pending: s.rank = await s.calc_lb_placement() else: s.status = SubmissionStatus.FAILED else: s.pp = s.sr = 0.0 if s.passed: s.status = SubmissionStatus.SUBMITTED else: s.status = SubmissionStatus.FAILED return s
class AsanPardakhtGateway(Gateway): """ Irankish TODO: transaction.pan not implemented Home: http://asanpardakht.ir/ Documentation: http://asanpardakht.ir/ipgdownload/ipgdoc.pdf """ __gateway_name__ = 'asan_pardakht' __gateway_unit__ = 'IRR' __config_params__ = [ 'key', 'iv', 'username', 'password', 'merchant_config_id', 'callback_url', 'proxies' ] _server_url = 'https://services.asanpardakht.net/paygate/merchantservices.asmx?WSDL' def __init__(self, config): super().__init__(config) self.rijndael = RijndaelCbc(key=base64.b64decode(config['key']), iv=base64.b64decode(config['iv']), padding=Pkcs7Padding(32), block_size=32) def _get_request_payload(self, transaction: Transaction, additional_data: str = '', accounts: List[Tuple[str, str]] = None): """ Get request payload :param transaction: :param additional_data: :param accounts: More (Shaba) accounts, Maximum 7 accounts can use. eg: [('shaba1', '100'), ('shaba2', '200'))] :return: """ accounts = [n for account in accounts for n in account] if accounts else [] return [ '1', self.config['username'], self.config['password'], str(transaction.order_id), str(transaction.amount), datetime.now().strftime('%Y%m%d %I%M%S'), additional_data, # Additional data maximum length is 100 characters self.config['callback_url'], '0' # Payment id (optional) ] + accounts def _get_encrypted_request(self, transaction: Transaction): return base64.b64encode( self.rijndael.encrypt(','.join( self._get_request_payload(transaction)).encode())) def _parse_callback_data(self, data: dict): data = self.rijndael.decrypt(base64.b64decode( data['ReturningParams'])).decode() exploded_data = data.split(',') return dict( amount=exploded_data[0], # Transaction amount sale_order_id=exploded_data[1], # Transaction Order ID ref_id=exploded_data[2], # Transaction ID res_code=exploded_data[3], # Result Code res_message=exploded_data[4], # Result Message pay_gate_trans_id=exploded_data[5], # Transaction inquiry id rrn=exploded_data[6], # Bank Reference ID last_four_digit_of_pan=exploded_data[ 7], # Last four digits of payer card ID ) @property def _encrypted_credentials(self): return base64.b64encode( self.rijndael.encrypt(','.join( [self.config['username'], self.config['password']]).encode())) def get_redirection(self, transaction) -> Redirection: return Redirection(url='https://asan.shaparak.ir/', body_params=dict(RefId=transaction.id, RedirctToIPGFORM='true'), method='post') def request_transaction(self, transaction: Transaction) -> Transaction: client = Client(self._server_url) if 'proxies' in self.config: client.transport.session.proxies = self.config['proxies'] try: params = { 'merchantConfigurationID': self.config['merchant_config_id'], 'encryptedRequest': self._get_encrypted_request(transaction) } result = client.service.RequestOperation(**params) if not result: raise TransactionError('AsanPardakht: invalid information.') if result[0:1] == '0': exploded_result = str(result).split( ',') # Should have two part [XX,YY] transaction.id = exploded_result[1] else: raise TransactionError( 'AsanPardakht: invalid information. code: %s' % str(result)) except zeep_exceptions.Fault: raise TransactionError('AsanPardakht: invalid information.') except zeep_exceptions.Error: raise GatewayNetworkError return transaction def validate_transaction(self, data: dict) -> Transaction: parsed_data = self._parse_callback_data(data) transaction = Transaction() transaction.id = parsed_data['ref_id'] transaction.meta = parsed_data if int(parsed_data['res_code']) == 0: transaction.validate_status = True return transaction def verify_transaction(self, transaction: Transaction, data): try: parsed_data = self._parse_callback_data(data) params = { 'merchantConfigurationID': int(self.config['merchant_config_id']), 'encryptedCredentials': self._encrypted_credentials, 'payGateTranID': parsed_data['pay_gate_trans_id'] } client = Client(self._server_url) if 'proxies' in self.config: client.transport.session.proxies = self.config['proxies'] verify_result = int(client.service.RequestVerification(**params)) if verify_result == 505: raise TransactionAlreadyPaidError( 'AsanPardakht: transaction already verified') elif verify_result != 500: raise TransactionError( 'AsanPardakht: invalid transaction, %s' % verify_result) reconcile_result = int( client.service.RequestReconciliation(**params)) if reconcile_result != 600: raise TransactionError( 'AsanPardakht: invalid transaction settlement, %s' % reconcile_result) except zeep_exceptions.Error: raise GatewayNetworkError return transaction