def decrypt_json(encrypted_data, secret_bytes_key, cipher_type='AES'): dct = serialization.BytesToDict( encrypted_data, encoding='utf-8', keys_to_text=True, values_to_text=True, ) if cipher_type == 'AES': cipher = AES.new( key=secret_bytes_key, mode=AES.MODE_CBC, iv=base64.b64decode(dct['iv'].encode('utf-8')), ) elif cipher_type == 'DES3': cipher = DES3.new( key=secret_bytes_key, mode=DES3.MODE_CBC, iv=base64.b64decode(dct['iv'].encode('utf-8')), ) else: raise Exception('unsupported cipher type') padded_data = cipher.decrypt(base64.b64decode(dct['ct'].encode('utf-8'))) if cipher_type == 'AES': raw_data = Padding.unpad( padded_data=padded_data, block_size=AES.block_size, ) elif cipher_type == 'DES3': raw_data = Padding.unpad( padded_data=padded_data, block_size=DES3.block_size, ) # TODO: remove salt from raw_data return raw_data
def decrypt_credential_v1(self, enc): try: enc = Util.base64dec_bytes(enc) iv = enc[:AES.block_size] cipher = AES.new(self.get_device_id_v1(), AES.MODE_CBC, iv) if sys.version_info < (3, 0): return py2_decode(Padding.unpad(padded_data=cipher.decrypt(enc[AES.block_size:]), block_size=32)) return Padding.unpad(padded_data=cipher.decrypt(enc[AES.block_size:]), block_size=32).decode('utf8') except Exception: self.log("Decrypt credentials error: " + traceback.format_exc()) return None
async def dump_method(cache: List[odict]): """Pads and encrypts the contents of a message""" args = [] for ord_d in cache: if ord_d["content"]: message = Padding.pad(bytes(ord_d["content"], "utf-8"), 16) encr_msg = self.aes.encrypt(message) else: encr_msg = "No message" ord_d["content"] = encr_msg args.append(list(ord_d.values())) # Loop end # =================================================== # | Example of database dumping, with postgresql # =================================================== # query = """ # INSERT INTO messagelog(messageid, authorid, guildid, channelid, date, content) # VALUES($1, $2, $3, $4, $5, $6) # ON CONFLICT(messageid, authorid) # DO NOTHING""" # # # here self.bot.db is an pool from -> asyncpg.create_pool() # async with self.bot.db.acquire() as connection: # async with connection.transaction(): # await self.bot.db.executemany(query, args) # =================================================== # Clear cache for new messages cache[:] = []
def msl_encrypt(msl_session, plaintext): """ msl_encrypt() @param msl_session: Dict of msl_session created by the client upon initialization @param plaintext: Plaintext to encrypt @return: JSON byte string of encryption envelope """ cbc_iv = os.urandom(16) encryption_envelope = { 'keyid': '%s_%s' % (msl_session['esn'], msl_session['session_keys']['sequence_number']), 'sha256': 'AA==', 'iv': base64.b64encode(cbc_iv).decode('utf8') } plaintext = Padding.pad(plaintext.encode('utf8'), 16) cipher = AES.new(msl_session['session_keys']['encryption_key'], AES.MODE_CBC, cbc_iv) ciphertext = cipher.encrypt(plaintext) encryption_envelope['ciphertext'] = base64.b64encode(ciphertext).decode( 'utf8') return json.dumps(encryption_envelope).encode('utf8')
def encrypt(plaintext, key, keylen=KEYLEN): """Encrypt bytes using AES-CBC with keys of length `keylen` (defaults to KEYLEN: 256 bits). Key is passed in KDF `PBKDF2` in order to protect weak keys against brute force attacks. @param plaintext: Data to be encrypted. @type plaintext: bytes @param key: Encryption passphrase. @type key: str, bytes @param keylen: Length of the key to use in bytes. Can be either 16, 24 or 32. @type keylen: str, bytes @return: The produced ciphertext. @rtype : bytes @raise ValueError: Incorrect padding. Happens if passphrase is incorrect. """ salt = Random.new().read(AES.block_size) iv = Random.new().read(AES.block_size) key = KDF.PBKDF2(key, salt, dkLen=keylen) plaintext = Padding.pad(plaintext, AES.block_size) cipher = AES.new(key, AES.MODE_CBC, iv=iv) return base64.b64encode(salt + iv + cipher.encrypt(plaintext))
def decrypt(pass_phrase, cipher_text): """ Decrypt encrypted data with provided pass phrase :param pass_phrase: Pass phrase :type pass_phrase: String :param cipher_text: Encrypted data :type cipher_text: String :return: Decrypted data :rtype: String """ mode = AES.MODE_CBC block_size = AES.block_size salt, initialization_vector, body = cipher_text.split('.') body = b64decode(body.encode('utf-8')) initialization_vector = b64decode(initialization_vector.encode('utf-8')) salt = b64decode(salt.encode('utf-8')) key = PBKDF2(pass_phrase, salt) cipher = AES.new(key, mode, initialization_vector) try: body = Padding.unpad(cipher.decrypt(body), block_size).decode('utf-8') except ValueError: # most likely a padding error which suggests incorrect password raise click.UsageError('Password incorrect') return body
def encrypt_json(raw_data, secret_bytes_key, cipher_type='AES'): # TODO: add salt to raw_data padded_data = Padding.pad( data_to_pad=raw_data, block_size=AES.block_size, ) if cipher_type == 'AES': cipher = AES.new( key=secret_bytes_key, mode=AES.MODE_CBC, ) elif cipher_type == 'DES3': cipher = DES3.new( key=secret_bytes_key, mode=DES3.MODE_CBC, ) else: raise Exception('unsupported cipher type') ct_bytes = cipher.encrypt(padded_data) dct = { 'iv': base64.b64encode(cipher.iv).decode('utf-8'), 'ct': base64.b64encode(ct_bytes).decode('utf-8'), } encrypted_data = serialization.DictToBytes(dct, encoding='utf-8') return encrypted_data
def decode(self, enc): enc = base64.b64decode(enc) iv = enc[:AES.block_size] cipher = AES.new(self.crypt_key, AES.MODE_CBC, iv) cipher2 = AES.new(self.crypt_key2, AES.MODE_CBC, iv) try: decoded = Padding.unpad(padded_data=cipher.decrypt( enc[AES.block_size:]), block_size=self.bs).decode('utf-8') except: decoded = Padding.unpad(padded_data=cipher2.decrypt( enc[AES.block_size:]), block_size=self.bs).decode('utf-8') return decoded
def encrypt(pass_phrase, data): """ Encrypt data using a pass phrase :param pass_phrase: Pass phrase to encrypt data with :type pass_phrase: String :param data: Data to encrypt :type data: String :return: Formatted string that contains salt, iv and encrypted message :rtype: String """ mode = AES.MODE_CBC block_size = AES.block_size salt = get_random_bytes(8) key = PBKDF2(pass_phrase, salt) body = Padding.pad(data.encode('utf-8'), block_size) initialization_vector = get_random_bytes(16) cipher = AES.new(key, mode, initialization_vector) # Now reassign salt, iv and body with their base64 encoded counterparts salt = b64encode(salt).decode('utf-8') initialization_vector = b64encode(initialization_vector).decode('utf-8') body = b64encode(cipher.encrypt(body)).decode('utf-8') return '{0}.{1}.{2}'.format(salt, initialization_vector, body)
async def get_between(self, ctx, first, last): await ctx.message.delete() if not(len(first) == 10 and first[2] == "-" and first[5] == "-"): await ctx.send("Wrong format for first date, valid format is: 'dd-mm-yyyy'") return if not(len(last) == 10 and last[2] == "-" and last[5] == "-"): await ctx.send("Wrong format for last date, valid format is: 'dd-mm-yyyy'") return date1 = datetime.datetime.strptime(first, "%d-%m-%Y") date2 = datetime.datetime.strptime(last, "%d-%m-%Y") query = """SELECT * FROM absence WHERE date BETWEEN $1 AND $2 ORDER BY date, userid;""" fetched = await self.bot.db.fetch(query, date1, date2) absence_list = "" for row in fetched: member = discord.utils.get(ctx.guild.members, id=row["userid"]) if member: excuse = self.aes.decrypt(row["excuse"]) excuse = Padding.unpad(excuse, 16) absence_list += f"{row['date'].strftime('%A %d-%m')} - {member.display_name}: {str(excuse)}\n" absenceembed = discord.Embed() absenceembed.title = f"All absence between {first} and {last}" absenceembed.description = absence_list if fetched else "No absence logged" await ctx.author.send(embed=absenceembed)
async def get_all(self, ctx): await ctx.message.delete() query = """SELECT * FROM absence WHERE guildid = $1 ORDER BY posted DESC, userid;""" fetched = await self.bot.db.fetch(query, ctx.guild.id) absence_list = "" for row in fetched: member = discord.utils.get(ctx.guild.members, id=row["userid"]) if member: excuse = self.aes.decrypt(row["excuse"]) excuse = Padding.unpad(excuse, 16).decode("utf-8") ab_id = row["id"] from_date = row['absentfrom'].strftime("%d/%m") to_date = row['absentto'].strftime("%d/%m") if from_date == to_date: date = from_date else: date = f"{from_date}-{to_date}" a_s = f"{ab_id} | {date} - {member.display_name}: {excuse}" a_s = Database.slice_string(a_s) if len(absence_list) + len(a_s) > 2000: break absence_list += f"{a_s:<65}\n" absenceembed = discord.Embed() absenceembed.title="All absence" absenceembed.description = absence_list if fetched else "No absence logged" await ctx.author.send(embed=absenceembed)
async def get_id(self, ctx, ab_id:int): query = """SELECT * FROM absence WHERE id = $1 AND guildid = $2""" await ctx.message.delete() fetched = await self.bot.db.fetchrow(query, ab_id, ctx.guild.id) if not fetched: await ctx.send("Couldn't find an absence with the id: {ab_id}") return member = discord.utils.get(ctx.guild.members, id=fetched["userid"]) excuse = self.aes.decrypt(fetched["excuse"]) excuse = Padding.unpad(excuse, 16).decode("utf-8") ab_id = fetched["id"] from_date = fetched['absentfrom'].strftime("%d/%m/%Y") to_date = fetched['absentto'].strftime("%d/%m/%Y") if from_date == to_date: date = from_date else: date = f"{from_date}-{to_date}" a_s = f"Absence id: {ab_id}\nDate: {date}\nExcuse: {excuse}" absenceembed = discord.Embed() absenceembed.set_author(name=member.display_name, icon_url=member.avatar_url) absenceembed.description = a_s[:2000] await ctx.author.send(embed=absenceembed)
def __decrypt_payload_chunks(self, payloadchunks): decrypted_payload = '' for chunk in payloadchunks: payloadchunk = json.JSONDecoder().decode(chunk) payload = payloadchunk.get('payload') decoded_payload = base64.standard_b64decode(payload) encryption_envelope = json.JSONDecoder().decode(decoded_payload) # Decrypt the text cipher = AES.new( self.encryption_key, AES.MODE_CBC, base64.standard_b64decode(encryption_envelope['iv'])) ciphertext = encryption_envelope.get('ciphertext') plaintext = cipher.decrypt(base64.standard_b64decode(ciphertext)) # unpad the plaintext plaintext = json.JSONDecoder().decode(Padding.unpad(plaintext, 16)) data = plaintext.get('data') # uncompress data if compressed if plaintext.get('compressionalgo') == 'GZIP': decoded_data = base64.standard_b64decode(data) data = zlib.decompress(decoded_data, 16 + zlib.MAX_WBITS) else: data = base64.standard_b64decode(data) decrypted_payload += data decrypted_payload = json.JSONDecoder().decode( decrypted_payload)[1]['payload']['data'] decrypted_payload = base64.standard_b64decode(decrypted_payload) return json.JSONDecoder().decode(decrypted_payload)
def encrypt_data(self, login_id, login_password, account_password, certificate_password, given_key=None, file_name=None): plain_data = ';'.join((login_id, login_password, account_password, certificate_password)) if file_name is not None: self.file_name = file_name # key setting random = Random.new() raw_key = given_key if raw_key is None: raw_key = self.raw_key set_key = self.set_key(raw_key) iv = random.read(AES.block_size) encoded_key = set_key.encode() key = strxor.strxor(encoded_key, iv) # Encryption encoded_data = plain_data.encode() padded_data = Padding.pad(encoded_data, AES.block_size) cipher = AES.new(key, AES.MODE_CBC, iv) encrypted_data = cipher.encrypt(padded_data) # File writing with open(self.file_name, 'wb') as file: file.write(iv) file.write(encrypted_data)
def decrypt_response(self, key, ciphertext): """ decrypt_response() Method to decrypt an encrypted response with provided key @param key: Key in bytes @param ciphertext: Ciphertext to decrypt in bytes @return: Decrypted response as a dict """ aes_cbc_ctx = AES.new(key, AES.MODE_CBC, iv=b'\0' * 16) try: plaintext = Padding.unpad(aes_cbc_ctx.decrypt(ciphertext), 16) except ValueError: self.logger.error('Error decrypting response') self.logger.error('Ciphertext:') self.logger.error(base64.b64encode(ciphertext).decode('utf8')) self.logger.error('Tried decrypting with key %s', base64.b64encode(key).decode('utf8')) raise ValueError('Error decrypting response') return json.loads(plaintext.decode('utf8'))
def _get_authentication_key_data(file_path, pin): """Open the auth key file""" from resources.lib.kodi import ui # Keep these imports within the method otherwise if the packages are not installed, # the addon crashes and the user does not read the warning message try: # The crypto package depends on the library installed (see Wiki) from Cryptodome.Cipher import AES from Cryptodome.Util import Padding except ImportError: from Crypto.Cipher import AES from Crypto.Util import Padding try: file_content = load_file(file_path) iv = '\x00' * 16 cipher = AES.new((pin + pin + pin + pin).encode("utf-8"), AES.MODE_CBC, iv.encode("utf-8")) decoded = Padding.unpad(padded_data=cipher.decrypt( base64.b64decode(file_content)), block_size=16) return json.loads(decoded.decode('utf-8')) except ValueError: # ValueError should always means wrong decryption due to wrong key ui.show_ok_dialog(get_local_string(30342), get_local_string(30106)) return '' except Exception as exc: # pylint: disable=broad-except LOG.warn('Exception raised: {}', exc) ui.show_ok_dialog(get_local_string(30342), get_local_string(30343)) return None
def decrypt_data(self, given_key=None, file_name=None): # data parsing if file_name is not None: self.file_name = file_name with open(self.file_name, 'rb') as file: iv = file.read(AES.block_size) encrypted_data = file.read() # key setting raw_key = given_key if raw_key is None: raw_key = self.raw_key set_key = self.set_key(raw_key) encoded_key = set_key.encode() key = strxor.strxor(encoded_key, iv) # decrypt data cipher = AES.new(key, AES.MODE_CBC, iv) decrypted_data = cipher.decrypt(encrypted_data) unpadded_data = Padding.unpad(decrypted_data, AES.block_size) plain_data = unpadded_data.decode() parsed_data = plain_data.split(';') self.login_id = parsed_data[0] self.login_password = parsed_data[1] self.account_password = parsed_data[2] self.certificate_password = parsed_data[3] return parsed_data
def encryption(data): crypt = DES.new(b'12345678', DES.MODE_ECB) content = json.dumps(data, separators=(',', ':')) content = Padding.pad(content.encode('utf8'), 8, 'pkcs7') content = crypt.encrypt(content) content = base64.b64encode(content) return content
def decrypt(ciphertext, key, keylen=KEYLEN): """Decrypt bytes using AES-CBC with keys of length `keylen` (defaults to KEYLEN: 256 bits). @param ciphertext: Data to be decrypted. @type ciphertext: bytes @param key: Encryption passphrase. @type key: str, bytes @param keylen: Length of the key to use in bytes. Can be either 16, 24 or 32. @type keylen: str, bytes @return: The decrypted ciphertext. @rtype : bytes @raise ValueError: Incorrect padding. Happens if passphrase is incorrect. """ ciphertext = base64.b64decode(ciphertext) salt = ciphertext[:AES.block_size] iv = ciphertext[AES.block_size:2 * AES.block_size] key = KDF.PBKDF2(key, salt, dkLen=keylen) cipher = AES.new(key, AES.MODE_CBC, iv=iv) return Padding.unpad(cipher.decrypt(ciphertext[2 * AES.block_size:]), AES.block_size)
async def get_user(self, ctx, member:discord.Member): query = """SELECT * FROM absence WHERE userid = $1 AND guildid = $2 ORDER BY id DESC;""" fetched = await self.bot.db.fetch(query, member.id, ctx.guild.id) absence_list = "" for row in fetched: excuse = self.aes.decrypt(row["excuse"]) excuse = Padding.unpad(excuse, 16).decode("utf-8") ab_id = row["id"] from_date = row['absentfrom'].strftime("%d/%m") to_date = row['absentto'].strftime("%d/%m") if from_date == to_date: date = from_date else: date = f"{from_date}-{to_date}" a_s = f"{ab_id} | {date} - {member.display_name}: {excuse}" a_s = Database.slice_string(a_s) if len(absence_list) + len(a_s) > 2000: break absence_list += f"{a_s:<65}\n" absenceembed = discord.Embed() absenceembed.set_author(name=member.display_name, icon_url=member.avatar_url) absenceembed.description = absence_list[:2000] await ctx.author.send(embed=absenceembed)
def encrypt_to_json(raw_data, secret_16bytes_key): # not in use at the moment cipher = AES.new(secret_16bytes_key, AES.MODE_CBC) ct_bytes = cipher.encrypt(Padding.pad(raw_data, AES.block_size)) iv = base64.b64encode(cipher.iv).decode('utf-8') ct = base64.b64encode(ct_bytes).decode('utf-8') result = json.dumps({'iv':iv, 'ct':ct, }, separators=(',', ':'), ) return result
def _encode(self, payload_data, con, path): payload_data = CryptoPadding.pad(payload_data, 16) cipher = self.get_cipher( con.master_key, con._.header.value.dynamic_header.encryption_iv.data) payload_data = cipher.encrypt(payload_data) return payload_data
def decrypt_from_json(encrypted_data, secret_16bytes_key): # not in use at the moment b64 = json.loads(encrypted_data) iv = base64.b64decode(b64['iv']) ct = base64.b64decode(b64['ct']) cipher = AES.new(secret_16bytes_key, AES.MODE_CBC, iv) result = Padding.unpad(cipher.decrypt(ct), AES.block_size) return result
def save_data(data, pin): raw = bytes(Padding.pad(data_to_pad=json.dumps(data).encode('utf-8'), block_size=16)) iv = '\x00' * 16 cipher = AES.new((str(pin) + str(pin) + str(pin) + str(pin)).encode('utf-8'), AES.MODE_CBC, iv.encode('utf-8')) encrypted_data = base64.b64encode(cipher.encrypt(raw)).decode('utf-8') file = open('NFAuthentication.key', 'w') file.write(encrypted_data) file.close()
def encrypt(raw_data, secret_16bytes_key): cipher = AES.new( key=secret_16bytes_key, mode=AES.MODE_CBC, ) ct_bytes = cipher.encrypt(Padding.pad(raw_data, AES.block_size)) output_data = dict(iv=cipher.iv, ct=ct_bytes) result = serialization.ObjectToString(output_data) return result
def decrypt_credential_v1(self, enc): try: enc = base64.b64decode(enc) iv = enc[:AES.block_size] cipher = AES.new(self.get_device_id_v1(), AES.MODE_CBC, iv) decoded = Padding.unpad(padded_data=cipher.decrypt(enc[AES.block_size:]), block_size=32).decode('utf-8') return decoded except: return None
def encrypt_credential_v1(self, raw): if sys.version_info < (3, 0): raw = bytes(raw) else: raw = bytes(raw, 'utf-8') raw = bytes(Padding.pad(data_to_pad=raw, block_size=32)) iv = Random.new().read(AES.block_size) cipher = AES.new(self.get_device_id_v1(), AES.MODE_CBC, iv) return Util.base64enc(iv + cipher.encrypt(raw))
async def content(self, ctx, content, limit: int=10): query = """ SELECT * FROM messages WHERE guild_id = $1 ORDER BY date desc LIMIT 1000;""" rows = await self.bot.db.fetch( query, ctx.guild.id) embed = discord.Embed( title=f"Fetched logs resembling search query") desc = "" topx = close_str(content, rows, limit) for _, record in reversed(topx): msgid, authorid, channelid, _, content, date = record date = date.strftime("%d/%m/%y %H:%M") msg = None try: msg = ctx.guild.get_message(msgid) except Exception: pass channel = "" try: channel = ctx.guild.get_channel(channelid).name except Exception: pass author = "" try: author = ctx.guild.get_member(authorid).mention except Exception: pass if msg: content = msg.content else: aes = AES.new(self.bot.secrets.ENCRYPT_KEY, AES.MODE_ECB) content = aes.decrypt(content) content = Padding.unpad(content, 16).decode("utf-8") prefix = f"{date} {author} #{channel}:" if len(prefix) > 25: prefix = prefix[:70] prefix += "\n" prefix = f"__**{prefix}**__" desc += f"{prefix}*{content}*\n" embed.description = f"{desc[:2000]}" if rows: await ctx.send(embed=embed) return await ctx.send(embed=discord.Embed(description="No logs available"))
def decrypt(encrypted_data, secret_16bytes_key): input_data = serialization.StringToObject(encrypted_data) cipher = AES.new( key=secret_16bytes_key, mode=AES.MODE_CBC, iv=input_data['iv'], ) padded_data = cipher.decrypt(input_data['ct']) result = Padding.unpad(padded_data, AES.block_size) return result
def encrypt(self) -> (bytes, bytes): """ Encrypts input text with input key and nonce using cipher specified on the instance and generates a tag that can be used to verify message integrity Returns a tuple with the encrypted text, hash for checking integrity, and nonce """ ciphertext, tag = self.set_key(self.nonce).encrypt_and_digest(Padding.pad(bytes(self.text, "utf-8"), 16)) return ciphertext, tag
def encode(self, raw): """ Encodes data :param data: Data to be encoded :type data: str :returns: string -- Encoded data """ raw = bytes(Padding.pad(data_to_pad=raw, block_size=self.bs)) iv = Random.new().read(AES.block_size) cipher = AES.new(self.crypt_key, AES.MODE_CBC, iv) return base64.b64encode(iv + cipher.encrypt(raw))
def decode(self, enc): """ Decodes data :param data: Data to be decoded :type data: str :returns: string -- Decoded data """ enc = base64.b64decode(enc) iv = enc[:AES.block_size] cipher = AES.new(self.crypt_key, AES.MODE_CBC, iv) decoded = Padding.unpad( padded_data=cipher.decrypt(enc[AES.block_size:]), block_size=self.bs).decode('utf-8') return decoded
def encrypt(self, data, esn, sequence_number): """ Encrypt the given Plaintext with the encryption key :param plaintext: :return: Serialized JSON String of the encryption Envelope """ iv = get_random_bytes(16) encryption_envelope = { 'ciphertext': '', 'keyid': esn + '_' + str(sequence_number), 'sha256': 'AA==', 'iv': base64.standard_b64encode(iv) } # Padd the plaintext plaintext = Padding.pad(data, 16) # Encrypt the text cipher = AES.new(self.encryption_key, AES.MODE_CBC, iv) citext = cipher.encrypt(plaintext) encryption_envelope['ciphertext'] = base64.standard_b64encode(citext) return encryption_envelope;
def decrypt(self, iv, data): cipher = AES.new(self.encryption_key, AES.MODE_CBC, iv) return Padding.unpad(cipher.decrypt(data), 16)