当前位置:首页>python>Python 日志最佳实践(2):Loguru 日志加解密

Python 日志最佳实践(2):Loguru 日志加解密

  • 2026-10-11 08:36:54
Python 日志最佳实践(2):Loguru 日志加解密

写在开头

我们在上一篇的文章里Python 日志最佳实践:Loguru 快速上手,简单介绍了loguru模块基础使用,已经学会了如何去记录一些日志到文件里,方便用于后期排查和分析,现在有一个更加专业点的安全问题,有时我们将做好的项目或软件打包到客户那边去的时候,往往不想明文日志直接暴露出来,这样容易被分析,被破解,这时我们可以采用对日志加密的方式,这样当用户出现问题时,只需要把日志回传过来,本地做下解密,就可以分析了。

cryptography

要加密日志的话,我们需要用到一个密码工具包,即cryptography模块。

#cryptography安装pip install cryptography

日志消息加密

接着我们来进一步优化上一篇文章中提到的logger_config.py文件,创建一个类,用来对消息的加密处理

import sysimport base64import hashlibfrom loguru import loggerfrom cryptography.fernet import Fernetclass EncryptedSink:    def __init__(self, filename, password):        #将配置的密码变成变成符合规范的32位的Key        sha256_hash = hashlib.sha256(password.encode()).digest()        key = base64.urlsafe_b64encode(sha256_hash)        self.file = open(filename, "ab")        self.fernet = Fernet(key)    def write(self, message):        #加密并写入        encrypted_data = self.fernet.encrypt(message.encode("utf-8"))        self.file.write(encrypted_data + b"\n")        self.file.flush()def setup_logging(log_path="app.log", password="hello123"): #默认密码hello123    #移除默认配置    logger.remove()    #控制台输出可以设置为明文,方便开发时调试    logger.add(sys.stdout, level="DEBUG", format="<green>{time}</green> | <level>{level}</level> | {message}")    #写到文件里的日志,则进行加密, 采用我们写好的Sink    enc_sink = EncryptedSink(log_path, password)    logger.add(enc_sink.write, level="DEBUG", enqueue=True)

加密测试

同样在main.py里做下输出测试

from loguru import loggerfrom logger_config import setup_loggingsetup_logging(log_path="app.enc.log") #在导入其他业务模块前执行, logger.debug("A debug message.")logger.info("An info message.")logger.success("A success message.")logger.warning("A warning message.")logger.error("An error message.")logger.critical("A critical message.")

我们这时再查看下日志输出,就可以看到,数据已经被加密了

日志消息解密

当然有加密,就必须要解密,我们就在本地再创建一个解密文件log_decryptor.py,专门用来解密这些日志文件,内容如下

import base64import hashlibfrom cryptography.fernet import Fernetdef decrypt_log_file(file_path, password="hello123"):    """    解密加密的日志文件并输出到控制台    :param file_path: 加密日志文件的路径 (如 app.enc.log)    :param password: 加密时使用的原始字符串密码    """    # 1. 密钥还原逻辑 (必须与加密时完全一致)    sha256_hash = hashlib.sha256(password.encode()).digest()    key = base64.urlsafe_b64encode(sha256_hash)    fernet = Fernet(key)    print(f"{'='*20} 开始解密日志 {'='*20}")    print(f"读取文件: {file_path}")    print(f"使用密码: {password}\n")    try:        with open(file_path, "rb") as f:            line_count = 0            for line in f:                line = line.strip()                if not line:                    continue                try:                    # 2. 执行解密                    decrypted_data = fernet.decrypt(line)                    # 3. 解码为字符串并打印 (去除末尾自带的换行符避免双倍换行)                    print(decrypted_data.decode("utf-8").strip())                    line_count += 1                except Exception as e:                    print(f"[解密失败] 该行数据可能损坏或密钥错误: {e}")            print(f"\n{'='*20} 解密完成 (共 {line_count} 行) {'='*20}")    except FileNotFoundError:        print(f"错误: 找不到文件 {file_path}")    except Exception as e:        print(f"系统错误: {e}")if __name__ == "__main__":    # 使用示例    # 也可以配合命令行参数使用: sys.argv[1]    target_file = "app.enc.log"    my_password = "hello123"    decrypt_log_file(target_file, my_password)

看下解密后的日志输出

写在最后

我们这样就简单完成的对日志的加密和解密,不过这里还可以做的更好一些,特别是我们密码部分,我们这里采用了硬编码方式,这种非常不建议,毕竟在逆向时很容易被看出来,如果用户软件有与服务器做通信,密码可以由服务器端传过去,这样客户那边是没办法直接看到的。需要对通信协议做分析才行。就需要更高的逆向技巧。

最新文章

随机文章