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)
示例#3
0
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
示例#13
0
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)
示例#14
0
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)
示例#15
0
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)