Пример #1
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)
Пример #2
0
def symmetric_encrypt_inline(update, context, uid_hash, text):
    '''Never use @run_asyn here.'''

    if sql.sql_check_user(uid_hash) != 1:
        # Make sure the inline user is registerd.
        return -1

    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:
            result_str = config.SERVER_ERROR_EXPRESSION
        else:
            result_str = 'sencrypted[%s%s%s]' % (
                nonce_str_hash, secret_key_str_hash, cipher_text_str)

    else:
        result_str = config.SERVER_ERROR_EXPRESSION

    return result_str
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)
Пример #5
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)