def command_symmetric_encryption(update, context): '''Switching encryption method''' uid_hash = encrypt.blake2b_hash(str(update.message.from_user.id)) sql.sql_update_encryption_mode(uid_hash, config.SYMMETRIC_ENCRYPTION_MODE) text = 'Start using symmetric encryption now. %s' % config.CALM_EXPRESSION update.message.reply_text(text=text, parse_mode=ParseMode.HTML)
def command_change_expire_date(update, context): '''Set the symmetric secret key expire date''' uid_hash = encrypt.blake2b_hash(str(update.message.from_user.id)) if sql.sql_check_user(uid_hash) != 1: return keyboard = keyboards.expiredate_unit_selection_keyboard() encryption_mode = sql.sql_get_encryption_mode(uid_hash) if encryption_mode == config.SYMMETRIC_ENCRYPTION_MODE: expire_time = sql.sql_get_secret_key_expire_date_from_config(uid_hash) text = 'Change the (default is %s) <b>symmetric encryption</b> expired time.' % ( str(timedelta(seconds=int(expire_time)))) elif encryption_mode == config.ASYMMETRIC_ENCRYPTION_MODE: expire_time = sql.sql_get_public_key_expire_date_from_config(uid_hash) text = 'Change the (default is %s) <b>asymmetric encryption</b> expired time.' % ( str(timedelta(seconds=int(expire_time)))) update.message.reply_text(text=text, parse_mode=ParseMode.HTML, reply_markup=keyboard) now_time = datetime.fromtimestamp(int(time.time())) text = '<b>Please select the unit you want to set the time for (now time is: %s):</b>' % now_time update.message.reply_text(text=text, parse_mode=ParseMode.HTML, reply_markup=keyboard)
def symmetric_encrypt_message(update, context, text): message = update.message uid = message.from_user.id uid_hash = encrypt.blake2b_hash(str(uid)) secret_key_bytes = encrypt.symmetric_key_generate() secret_key_str = encrypt.convert_bytes_to_str(secret_key_bytes) secret_key_str_hash = encrypt.sha256_hash(secret_key_str) sql.sql_insert_secret_key(uid_hash, secret_key_str_hash, secret_key_str) encrypt_result_dict = encrypt.symmetric_encryption(secret_key_bytes, text) if encrypt_result_dict: cipher_text_bytes = encrypt_result_dict['cipher_text'] cipher_text_str = encrypt.convert_bytes_to_str(cipher_text_bytes) nonce_bytes = encrypt_result_dict['nonce'] nonce_str = encrypt.convert_bytes_to_str(nonce_bytes) nonce_str_hash = encrypt.sha256_hash(nonce_str) if sql.sql_insert_nonce(uid_hash, nonce_str_hash, nonce_str) != 0: text = config.SERVER_ERROR_EXPRESSION else: text = 'sencrypted[%s%s%s]' % (nonce_str_hash, secret_key_str_hash, cipher_text_str) else: text = config.SERVER_ERROR_EXPRESSION update.message.reply_text(text=text, parse_mode=ParseMode.HTML)
def command_day(update, context): uid_hash = encrypt.blake2b_hash(str(update.message.from_user.id)) if sql._sql_check_uid(uid_hash) != 1: return config.expire_date_unit_select_dict[uid_hash] = 'day' config.command_expire_list.append(uid_hash) text = 'How long does it take to expire (<b>day</b>)?' update.message.reply_text(text=text, parse_mode=ParseMode.HTML)
def command_change_time_to_live(update, context): uid_hash = encrypt.blake2b_hash(str(update.message.from_user.id)) if sql.sql_check_user(uid_hash) != 1: return keyboard = keyboards.inline_chtm_keyboard() text = 'Please choose the message decryption time to live value.' update.message.reply_text(text=text, parse_mode=ParseMode.HTML, reply_markup=keyboard)
def command_destroy(update, context): '''Delete all the user's key''' uid_hash = encrypt.blake2b_hash(str(update.message.from_user.id)) sql_status = sql.sql_delete_user_all_key(uid_hash) if sql_status != 0: text = '<b>There are some problems when deleting, but the problem is not big.</b>' else: text = '<b>Finish!</b>' update.message.reply_text(text=text, parse_mode=ParseMode.HTML)
def command_keygen(update, context): '''Generate the new key for user. ''' uid = update.message.from_user.id uid_hash = encrypt.blake2b_hash(str(uid)) if sql._sql_check_uid(uid_hash) != 1: return uid_hash_list = list() uid_hash_list.append(uid_hash) if config.keygen_confirm_dict.__contains__(uid_hash): if config.keygen_confirm_dict[uid_hash] == False: config.keygen_confirm_dict[uid_hash] = True config.keygen_confirm_dict.pop(uid_hash) config.command_expire_list.remove(uid_hash) asymmetric_key_dict = encrypt.asymmetric_key_generate() private_key_hex = encrypt.convert_bytes_to_str( asymmetric_key_dict['private_key']) public_key_hex = encrypt.convert_bytes_to_str( asymmetric_key_dict['public_key']) if sql.sql_update_expired_public_key(uid_hash_list, public_key_hex) == -1: text = 'Update asymmetric key failed.' update.message.reply_text(text=text, parse_mode=ParseMode.HTML) return text = ( 'Generate success, this is your new <b>Asymmetric Secret Key</b>. %s' 'The database will be updated automatically. ' 'Similarly, we will not store this key, so please keep it safe.' ) % (config.GOOD_EXPRESSION) update.message.reply_text(text=text, parse_mode=ParseMode.HTML) text = '<b>%s</b>' % private_key_hex update.message.reply_text(text=text, parse_mode=ParseMode.HTML) else: text = ( 'Please confirm if you need to really regenerate <b>Asymmetric Key</b>. ' 'If you regenerate the key, the old chat message no longer supports decryption reading.' 'But we also <b>recommend</b> that you reset this key periodically to avoid exhaustive attacks.' 'After all, there are quantum computers now.' 'If you confirm to regenerate this key, click /keygen button <b>again</b>.' ) # False mean that the program will waiting for the user confirmation. config.keygen_confirm_dict[uid_hash] = False config.command_expire_list.append(uid_hash) update.message.reply_text(text=text, parse_mode=ParseMode.HTML)
def command_register(update, context): '''For new user. ''' uid = update.message.from_user.id text = ('We got your user id to be this:\n<b>%d</b>\n' 'This will be your only username in the system.') % uid update.message.reply_text(text=text, parse_mode=ParseMode.HTML) '''The process_dict should contain these thing. private_key will not store in the database. { 'uid_hash', ...(64B hex string), 'public_key': ...(64B hex string), 'create_time': ...(int) } ''' asymmetric_key_dict = encrypt.asymmetric_key_generate() private_key_bytes = asymmetric_key_dict['private_key'] public_key_bytes = asymmetric_key_dict['public_key'] private_key_hex_str = encrypt.convert_bytes_to_str(private_key_bytes) public_key_hex_str = encrypt.convert_bytes_to_str(public_key_bytes) process_dict = dict() process_dict['uid_hash'] = encrypt.blake2b_hash(str(uid)) process_dict['public_key'] = public_key_hex_str # Use the timestamp(int). process_dict['create_time'] = int(time.time()) status = sql.sql_register(process_dict) if status == -1: text = '<b>Register failed, please contact your administrator! %s</b>' % config.SURPRISED_EXPRESSION update.message.reply_text(text=text, parse_mode=ParseMode.HTML) return elif status == 1: text = '<b>You have already registered, please do not register again! %s</b>' % config.NO_EXPRESSION update.message.reply_text(text=text, parse_mode=ParseMode.HTML) return else: text = '<b>Register success! %s</b>' % config.GOOD_EXPRESSION update.message.reply_text(text=text, parse_mode=ParseMode.HTML) # We show the private_key to user, not store in the server. text = ( 'Please keep this <b>asymmetric private key</b> in a safe place, don\'t let it leak to others. %s' 'We won\'t store this key on the server. If you lose the key or regenerate a new key and replace it, the message encrypted with this key will be permanently lost.' ) % config.GOOD_EXPRESSION update.message.reply_text(text=text, parse_mode=ParseMode.HTML) text = '<b>%s</b>' % private_key_hex_str update.message.reply_text(text=text, parse_mode=ParseMode.HTML)
def command_account(update, context): '''Show the account details for user. ''' uid = update.message.from_user.id uid_hash = encrypt.blake2b_hash(str(uid)) if sql.sql_check_user(uid_hash) != 1: re_text = "<b>Please register first!</b>" update.message.reply_text(text=re_text, parse_mode=ParseMode.HTML) return expire_data_dict = sql.sql_get_all_expire_date(uid_hash) date_s = str(timedelta(seconds=int(expire_data_dict['sexpire_date']))) date_a = datetime.fromtimestamp( int(sql.sql_get_public_key_expire_date_from_public_key(uid_hash))) date_aa = str(timedelta(seconds=int(expire_data_dict['aexpire_date']))) date_n = datetime.fromtimestamp(int(time.time())) encryption_mode = sql.sql_get_encryption_mode(uid_hash) if encryption_mode == config.SYMMETRIC_ENCRYPTION_MODE: encryption_mode = 'Symmetric' elif encryption_mode == config.ASYMMETRIC_ENCRYPTION_MODE: encryption_mode = 'Asymmetric' uid_text = 'UID: <b>%d</b>\nEncryption mode: <b>%s</b>\nUTC time now: <b>%s</b>' % ( uid, encryption_mode, date_n) update.message.reply_text(text=uid_text, parse_mode=ParseMode.HTML) symmetirc_text = 'Each symmetric secret key expire interval (UTC): <b>%s</b>' % ( date_s) update.message.reply_text(text=symmetirc_text, parse_mode=ParseMode.HTML) asymmetric_text = ( 'Asymmetric public key (Note: we will not save the private key): <b>%s</b>\nExpire date (UTC): <b>%s</b>\n' 'Each asymmetric public key expire interval (UTC): <b>%s</b>\n' 'If your public key become 0, that mean your public key is expired, you need to re-gen new key.' ) % (sql.sql_get_public_key(uid_hash), date_a, date_aa) update.message.reply_text(text=asymmetric_text, parse_mode=ParseMode.HTML)
def command_emoji(update, context): '''Enable the emoji encryption. ''' uid = update.message.from_user.id uid_hash = encrypt.blake2b_hash(str(uid)) emoji_mode = sql.sql_get_emoji_mode(uid_hash) if emoji_mode == 0: text = 'Start using emoji encryption now. %s' % config.CALM_EXPRESSION new_emoji_mode = 1 elif emoji_mode == 1: text = 'Stop using emoji encryption now. %s' % config.CALM_EXPRESSION new_emoji_mode = 0 else: text = config.SERVER_ERROR_EXPRESSION update.message.reply_text(text=text, parse_mode=ParseMode.HTML) return if sql.sql_update_emoji_mode(uid_hash, new_emoji_mode): text = config.SERVER_ERROR_EXPRESSION update.message.reply_text(text=text, parse_mode=ParseMode.HTML)
def command_query_back(update, context): # print(dir(update)) # print(update.edited_message) # print(update.effective_message) # print(dir(update.callback_query)) # print(update.callback_query) # print(update.callback_query.message) # print(dir(update.callback_query.edit_message_text)) uid = update.callback_query.from_user.id uid_hash = encrypt.blake2b_hash(str(uid)) if update.callback_query.data: query = update.callback_query.data # print(query) else: return if query == 'chtm-u': command_query_back_chtm(update, context, uid_hash, config.DEFAULT_MAX_DECRYPTION_TIME) elif query == 'chtm-1': command_query_back_chtm(update, context, uid_hash, 1) elif query == 'chtm-2': command_query_back_chtm(update, context, uid_hash, 2) elif query == 'chtm-3': command_query_back_chtm(update, context, uid_hash, 3) elif query == 'chtm-5': command_query_back_chtm(update, context, uid_hash, 5) elif query == 'chtm-8': command_query_back_chtm(update, context, uid_hash, 8) return
def command_inline(update, context): '''Process the message from inline query''' # type(text) is str. text = update.inline_query.query text = text.strip() if len(text) == 0: return 0 uuid_me = uuid.uuid4() results = list() uid = update.inline_query.from_user.id uid_hash = encrypt.blake2b_hash(str(uid)) if config.maintenance_mode: results.append( InlineQueryResultArticle( id=uuid_me, title=config.SERVER_ERROR_EXPRESSION, description=config.MAINTENANCE_EXPRESSION, input_message_content=InputTextMessageContent( config.MAINTENANCE_EXPRESSION, parse_mode=ParseMode.HTML))) try: update.inline_query.answer(results, cache_time=60, is_personal=True) except Exception: pass return 0 if sql.sql_check_user(uid_hash) != 1: plain_text = 'Sorry, we can\'t decrypt this ciphertext' results.append( InlineQueryResultArticle( id=uuid_me, title=config.SERVER_ERROR_EXPRESSION, description=plain_text, input_message_content=InputTextMessageContent( config.SERVER_ERROR_EXPRESSION, parse_mode=ParseMode.HTML))) try: update.inline_query.answer(results, cache_time=60, is_personal=True) except Exception: pass return 0 if 'seinline[' in text: try: cipher_text_hash = text.split('seinline')[1][1:-1] except IndexError: return -1 if len(cipher_text_hash) == 0 or not check_string(cipher_text_hash): return -1 # Check the cipher_text. cipher_text = sql.sql_get_cipher_text(cipher_text_hash) # print('commands(cipher_text): ' + cipher_text) if not cipher_text: # try: # bot.editMessageText( # message_id=update.callback_query.message.message_id, # chat_id=update.callback_query.message.chat.id, # text='This ciphertext has expired. %s' % ( # config.GOOD_EXPRESSION), # parse_mode=ParseMode.HTML, # # reply_markup=keyboards.inline_chtm_keyboard() # ) # except Exception: # pass results.append( InlineQueryResultArticle( id=uuid_me, title=config.EXPIRE_ERROR_EXPRESSION, description='please check your input', input_message_content=InputTextMessageContent( config.SERVER_ERROR_EXPRESSION, parse_mode=ParseMode.HTML))) try: update.inline_query.answer(results, cache_time=60, is_personal=True) except Exception: pass return -1 # Check the plain_text. plain_text = messages.symmetric_decrypt_inline(update, context, uid_hash, cipher_text) # print('commands(plain_text): ' + plain_text) if not plain_text: results.append( InlineQueryResultArticle( id=uuid_me, title=config.SERVER_ERROR_EXPRESSION, description='please check your input', input_message_content=InputTextMessageContent( config.SERVER_ERROR_EXPRESSION, parse_mode=ParseMode.HTML))) try: update.inline_query.answer(results, cache_time=60, is_personal=True) except Exception: pass return -1 results.append( InlineQueryResultArticle( id=uuid_me, title='De-Result', description=plain_text, input_message_content=InputTextMessageContent( plain_text, parse_mode=ParseMode.HTML))) try: update.inline_query.answer(results, cache_time=60, is_personal=True) except Exception: pass else: cipher_text = messages.symmetric_encrypt_inline( update, context, uid_hash, text) cipher_text_hash = encrypt.sha256_hash(cipher_text) if not cipher_text or cipher_text == -1 or not cipher_text_hash: results.append( InlineQueryResultArticle( id=uuid_me, title=config.SERVER_ERROR_EXPRESSION, description='please check your input', input_message_content=InputTextMessageContent( config.SERVER_ERROR_EXPRESSION, parse_mode=ParseMode.HTML))) try: update.inline_query.answer(results, cache_time=60, is_personal=True) except Exception: pass return -1 switch_inline_query_str = 'seinline[%s]' % cipher_text_hash keyboard = keyboards.inline_keyboard(switch_inline_query_str) sql.sql_insert_cipher_text(uid_hash, cipher_text_hash, cipher_text) # Disable the sql_get_emoji_mode in the inline mode. # if 1 == 2: if sql.sql_get_emoji_mode(uid_hash): # if user want to use the emoji encrption. try: cipher_data = cipher_text.split('sencrypted')[1][1:-1] # print(cipher_text) except IndexError: return -1 if len(cipher_data) == 0 or not check_string(cipher_data): return -1 emoji_text = encrypt.convert_str_to_emoji_c(cipher_data) # print(emoji_text) # emoji_text = 'sencrypted[%s]' % emoji_text results.append( InlineQueryResultArticle( id=uuid_me, title='En-Result', description='id: %s' % str(uuid_me)[0:8], input_message_content=InputTextMessageContent( emoji_text, parse_mode=ParseMode.HTML), reply_markup=keyboard)) try: update.inline_query.answer(results, cache_time=60, is_personal=True) except Exception: pass else: results.append( InlineQueryResultArticle( id=uuid_me, title='En-Result', description='id: %s' % str(uuid_me)[0:8], input_message_content=InputTextMessageContent( cipher_text, parse_mode=ParseMode.HTML), reply_markup=keyboard)) try: update.inline_query.answer(results, cache_time=60, is_personal=True) except Exception: pass
def process_message_private(update, context): '''For private chat use.''' message = update.message uid = message.from_user.id uid_hash = encrypt.blake2b_hash(str(uid)) # Ignore the command message. if message.text and message.text[0] == r'/': return if sql.sql_check_user(uid_hash) != 1: # If the not registed user want to decrypted this message. # Be safety considering, not do decrypt job. plain_text = 'Sorry, we can\'t decrypt this ciphertext' update.message.reply_text(text=plain_text, parse_mode=ParseMode.HTML) return encryption_mode = sql.sql_get_encryption_mode(uid_hash) if config.expire_date_unit_select_dict.__contains__(uid_hash): if encryption_mode == config.SYMMETRIC_ENCRYPTION_MODE: if config.expire_date_unit_select_dict[uid_hash] == 'second': try: second = int(message.text) except Exception: text = '<b>Please check your input.</b>' update.message.reply_text(text=text, parse_mode=ParseMode.HTML) return sql.sql_update_symmetric_expire_date(uid_hash, second) config.expire_date_unit_select_dict.pop(uid_hash) config.command_expire_list.remove(uid_hash) text = '<b>Update success, please use /account command to see.</b>' update.message.reply_text(text=text, parse_mode=ParseMode.HTML) elif config.expire_date_unit_select_dict[uid_hash] == 'minute': try: minute = int(message.text) * 60 except Exception: text = '<b>Please check your input.</b>' update.message.reply_text(text=text, parse_mode=ParseMode.HTML) return sql.sql_update_symmetric_expire_date(uid_hash, minute) config.expire_date_unit_select_dict.pop(uid_hash) config.command_expire_list.remove(uid_hash) text = '<b>Update success, please use /account command to see.</b>' update.message.reply_text(text=text, parse_mode=ParseMode.HTML) elif config.expire_date_unit_select_dict[uid_hash] == 'hour': try: hour = int(message.text) * 60 * 60 except Exception: text = '<b>Please check your input.</b>' update.message.reply_text(text=text, parse_mode=ParseMode.HTML) return sql.sql_update_symmetric_expire_date(uid_hash, hour) config.expire_date_unit_select_dict.pop(uid_hash) config.command_expire_list.remove(uid_hash) text = '<b>Update success, please use /account command to see.</b>' update.message.reply_text(text=text, parse_mode=ParseMode.HTML) elif config.expire_date_unit_select_dict[uid_hash] == 'day': try: day = int(message.text) * 60 * 60 * 24 except Exception: text = '<b>Please check your input.</b>' update.message.reply_text(text=text, parse_mode=ParseMode.HTML) return sql.sql_update_symmetric_expire_date(uid_hash, day) config.expire_date_unit_select_dict.pop(uid_hash) config.command_expire_list.remove(uid_hash) text = '<b>Update success, please use /account command to see.</b>' update.message.reply_text(text=text, parse_mode=ParseMode.HTML) if encryption_mode == config.ASYMMETRIC_ENCRYPTION_MODE: if config.expire_date_unit_select_dict[uid_hash] == 'second': try: second = int(message.text) except Exception: text = '<b>Please check your input.</b>' update.message.reply_text(text=text, parse_mode=ParseMode.HTML) return sql.sql_update_asymmetric_expire_date(uid_hash, second) config.expire_date_unit_select_dict.pop(uid_hash) config.command_expire_list.remove(uid_hash) text = '<b>Update success, please use /account command to see.</b>' update.message.reply_text(text=text, parse_mode=ParseMode.HTML) elif config.expire_date_unit_select_dict[uid_hash] == 'minute': try: minute = int(message.text) * 60 except Exception: text = '<b>Please check your input.</b>' update.message.reply_text(text=text, parse_mode=ParseMode.HTML) return sql.sql_update_asymmetric_expire_date(uid_hash, minute) config.expire_date_unit_select_dict.pop(uid_hash) config.command_expire_list.remove(uid_hash) text = '<b>Update success, please use /account command to see.</b>' update.message.reply_text(text=text, parse_mode=ParseMode.HTML) elif config.expire_date_unit_select_dict[uid_hash] == 'hour': try: hour = int(message.text) * 60 * 60 except Exception: text = '<b>Please check your input.</b>' update.message.reply_text(text=text, parse_mode=ParseMode.HTML) return sql.sql_update_asymmetric_expire_date(uid_hash, hour) config.expire_date_unit_select_dict.pop(uid_hash) config.command_expire_list.remove(uid_hash) text = '<b>Update success, please use /account command to see.</b>' update.message.reply_text(text=text, parse_mode=ParseMode.HTML) elif config.expire_date_unit_select_dict[uid_hash] == 'day': try: day = int(message.text) * 60 * 60 * 24 except Exception: text = '<b>Please check your input.</b>' update.message.reply_text(text=text, parse_mode=ParseMode.HTML) return sql.sql_update_asymmetric_expire_date(uid_hash, day) config.expire_date_unit_select_dict.pop(uid_hash) config.command_expire_list.remove(uid_hash) text = '<b>Update success, please use /account command to see.</b>' update.message.reply_text(text=text, parse_mode=ParseMode.HTML) # Do the encryption or decryption elif message.text: # First check the message whether emoji text. # if encrypt.detect_encrypted_emoji(message.text): if encrypt.detect_encrypted_emoji_c(message.text): # text = encrypt.convert_emoji_to_str(message.text) text = encrypt.convert_emoji_to_str_c(message.text) text = 'sencrypted[%s]' % text # print(text) symmetric_decrypt_message(update, context, text) elif encryption_mode == config.SYMMETRIC_ENCRYPTION_MODE: if 'sencrypted[' in message.text: # This is encrypted message, we need to decrypt it. # Fist check out the user is registerd. symmetric_decrypt_message(update, context, message.text) elif 'seinline[' in message.text: # text = sql.sql_get_cipher_text(message.text) # symmetric_decrypt_message( # update, context, text) text = '<b>Please use the inline mode to decrypted this message!</b>' update.message.reply_text(text=text, parse_mode=ParseMode.HTML) elif sql.sql_get_emoji_mode(uid_hash): symmetric_encrypt_message_emoji(update, context, message.text) else: symmetric_encrypt_message(update, context, message.text) elif encryption_mode == config.ASYMMETRIC_ENCRYPTION_MODE: if 'aencrypted[' in message.text: # This is encrypted message, we need to decrypt it. asymmetric_decrypt_message(update, context, message.text) elif config.private_key_dict.__contains__(uid_hash): if config.private_key_dict[uid_hash] == 'encrypt': '''For the asymmetric encryption''' asymmetric_encrypt_message(update, context, message.text) elif config.private_key_dict[uid_hash] == 'decrypt': '''In here, we just sent out ciphertext to the bot, now the bot still has to wait for our private key. If use the symmetric key to encrypted or decrypted, this step here will not need, the symmetric encryption just return the result. ''' asymmetric_decrypt_message(update, context, message.text) elif len(config.private_key_dict[uid_hash]) != 0: asymmetric_encrypt_message(update, context, message.text) else: asymmetric_encrypt_message(update, context, message.text) elif message.photo: # We get the last file_id which is the biggest size. photo_dict = message.photo[-1] file_id = photo_dict['file_id'] photo_text = 'photo[%s]' % file_id if encryption_mode == config.SYMMETRIC_ENCRYPTION_MODE: symmetric_encrypt_message(update, context, photo_text) elif encryption_mode == config.ASYMMETRIC_ENCRYPTION_MODE: asymmetric_encrypt_message(update, context, photo_text)
def asymmetric_encrypt_message(update, context, text): '''Start doing core work now.''' message = update.message uid = message.from_user.id uid_hash = encrypt.blake2b_hash(str(uid)) if config.private_key_dict.__contains__(uid_hash): if config.private_key_dict[uid_hash] == 'encrypt': # Check the private key length. user_private_key_str = (str(message.text)).strip() if len(user_private_key_str) != 64: text = 'Please check your private key value.' update.message.reply_text(text=text, parse_mode=ParseMode.HTML) config.private_key_dict.pop(uid_hash) return text = '[encrypt]Please input the target user id.' update.message.reply_text(text=text, parse_mode=ParseMode.HTML) config.private_key_dict[uid_hash] = user_private_key_str return else: target_uid = (str(message.text)).strip() target_uid_hash = encrypt.blake2b_hash(target_uid) # print('e-target_hash: ' + target_uid_hash) target_public_key_str = sql.sql_get_public_key(target_uid_hash) if target_public_key_str == None: text = 'Sorry, we can not found such user.' update.message.reply_text(text=text, parse_mode=ParseMode.HTML) return config.public_key_dict[uid_hash] = target_public_key_str user_private_key_bytes = encrypt.convert_str_to_bytes( config.private_key_dict[uid_hash]) target_public_key_bytes = encrypt.convert_str_to_bytes( config.public_key_dict[uid_hash]) encrypt_result_dict = encrypt.asymmetric_encryption( user_private_key_bytes, target_public_key_bytes, config.plain_text_dict[uid_hash]) if encrypt_result_dict: cipher_text_bytes = encrypt_result_dict['cipher_text'] cipher_text_str = encrypt.convert_bytes_to_str( cipher_text_bytes) nonce_bytes = encrypt_result_dict['nonce'] nonce_str = encrypt.convert_bytes_to_str(nonce_bytes) nonce_str_hash = encrypt.sha256_hash(nonce_str) if sql.sql_insert_nonce(uid_hash, nonce_str_hash, nonce_str): text = config.SERVER_ERROR_EXPRESSION else: text = 'aencrypted[%s%s%s]' % (nonce_str_hash, uid_hash, cipher_text_str) update.message.reply_text(text=text, parse_mode=ParseMode.HTML) config.private_key_dict.pop(uid_hash) config.public_key_dict.pop(uid_hash) config.plain_text_dict.pop(uid_hash) config.command_expire_list.remove(uid_hash) else: config.plain_text_dict[uid_hash] = text config.private_key_dict[uid_hash] = 'encrypt' config.command_expire_list.append(uid_hash) text = '[encrypt]Please input your private key.' update.message.reply_text(text=text, parse_mode=ParseMode.HTML)
def asymmetric_decrypt_message(update, context, text): '''As you see''' message = update.message uid = message.from_user.id uid_hash = encrypt.blake2b_hash(str(uid)) if config.private_key_dict.__contains__(uid_hash): if config.private_key_dict[uid_hash] == 'decrypt': # Check the private key length. user_private_key_str = (str(message.text)).strip() if len(user_private_key_str) != 64 or not check_string( user_private_key_str): text = 'Please check your private key value.' update.message.reply_text(text=text, parse_mode=ParseMode.HTML) config.private_key_dict.pop(uid_hash) config.public_key_dict.pop(uid_hash) config.nonce_dict.pop(uid_hash) config.cipher_txt_dict.pop(uid_hash) return nonce_bytes = encrypt.convert_str_to_bytes( config.nonce_dict[uid_hash]) cipher_text_bytes = encrypt.convert_str_to_bytes( config.cipher_txt_dict[uid_hash]) # We get the target uid's public key. target_public_key_str = config.public_key_dict[uid_hash] if not target_public_key_str: text = 'No such user.' update.message.reply_text(text=text, parse_mode=ParseMode.HTML) return user_private_key_bytes = encrypt.convert_str_to_bytes( user_private_key_str) target_public_key_bytes = encrypt.convert_str_to_bytes( target_public_key_str) # print('d-target-pk: ' + target_public_key_str) plain_text = encrypt.asymmetric_decryption( user_private_key_bytes, target_public_key_bytes, nonce_bytes, cipher_text_bytes) config.private_key_dict.pop(uid_hash) config.public_key_dict.pop(uid_hash) config.nonce_dict.pop(uid_hash) config.cipher_txt_dict.pop(uid_hash) config.command_expire_list.remove(uid_hash) # print(plain_text) if plain_text == None: update.message.reply_text( text='Sorry, we can\'t decrypt this ciphertext.', parse_mode=ParseMode.HTML) elif 'photo[' in plain_text and ']' in plain_text: file_id = plain_text[6:-1] update.message.reply_photo(photo=file_id) update.message.reply_text(text=plain_text, parse_mode=ParseMode.HTML) else: try: cipher_data = text.split('aencrypted')[1][1:-1] except IndexError: return if len(cipher_data) == 0: return -1 nonce_str_hash = cipher_data[0:64] if not check_string(nonce_str_hash) or len(nonce_str_hash) == 0: return -1 target_uid_hash = cipher_data[64:128] if not check_string(target_uid_hash) or len(target_uid_hash) == 0: return -1 cipher_text_str = cipher_data[128:-1] + cipher_data[-1] if not check_string(cipher_text_str) or len(cipher_text_str) == 0: return -1 nonce_str = sql.sql_nonce_query(nonce_str_hash) config.private_key_dict[uid_hash] = 'decrypt' config.public_key_dict[uid_hash] = sql.sql_get_public_key( target_uid_hash) config.nonce_dict[uid_hash] = nonce_str config.cipher_txt_dict[uid_hash] = cipher_text_str config.command_expire_list.append(uid_hash) text = '[decrypt]Please input your private key.' update.message.reply_text(text=text, parse_mode=ParseMode.HTML)