Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/288.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python日志模块加密_Python_Python 2.7_Logging_Encryption - Fatal编程技术网

Python日志模块加密

Python日志模块加密,python,python-2.7,logging,encryption,Python,Python 2.7,Logging,Encryption,我有一个带有日志的python脚本。现在我想使用pycrypto用AES加密日志 import logging import base64 from Crypto.Cipher import AES aes = AES.new(cryptoKey) logging.basicConfig(filename='example.log',level=logging.DEBUG) # file name, not custom file logging.info('text') 在将其写入日志之前

我有一个带有日志的python脚本。现在我想使用pycrypto用AES加密日志

import logging
import base64
from Crypto.Cipher import AES
aes = AES.new(cryptoKey)
logging.basicConfig(filename='example.log',level=logging.DEBUG) #  file name, not custom file
logging.info('text')

在将其写入日志之前,我想使用
base64.b64编码(aes.encrypt('#logging text#'))
。什么是最有效的加密方式?

加密不仅仅是转发数据。我建议您编写自己的日志格式化程序,并将其设置为根格式化程序——这样,无论您从应用程序中的何处登录,甚至是不受代码控制的部分,它都将始终经过一层加密。比如说:

import base64
import logging
from Crypto.Cipher import AES
from Crypto.Hash import SHA256
from Crypto import Random

class EncryptedLogFormatter(logging.Formatter):

    # make sure that the `key` is a byte stream on Python 3.x
    def __init__(self, key, fmt=None, datefmt=None):
        self._key = SHA256.new(key).digest()  # use SHA-256 for a proper-sized AES key
        super(EncryptedLogFormatter, self).__init__(fmt=fmt, datefmt=datefmt)

    def format(self, record):
        message = record.msg  # log message to encrypt, if any
        if message:  # no sense to encrypt empty log messages
            # on Python 3.x encode first: message = message.encode("utf-8")
            iv = Random.new().read(AES.block_size)  # we'll be using CBC so generate an IV
            cipher = AES.new(self._key, AES.MODE_CBC, iv)
            # AES demands all blocks to be of `AES.block_size` so we have to pad the message
            # you can use any padding you prefer, I think PKCS#7 is the best option
            padding = AES.block_size - len(message) % AES.block_size
            # pad the message...
            message += chr(padding) * padding # Python 3.x: bytes([padding]) * padding
            message_enc = iv + cipher.encrypt(message)  # add iv and encrypt
            # finally, replace our plain-text message with base64 encoded encrypted one
            record.msg = base64.b64encode(message_enc).decode("latin-1")
        # you can do more here, even print out your own string but we'll just
        # pass it to the default formatter now that the message is encrypted
        # so that it can respect other formatting options.
        return super(EncryptedLogFormatter, self).format(record)
import base64
from Crypto.Cipher import AES
from Crypto.Hash import SHA256

# make sure that the `key` is a byte stream on Python 3.x
def log_decryptor(key, stream):  # assume the stream can be iterated line-by-line
    key = SHA256.new(key).digest()  # same derivation as in the EncryptedLogFormatter
    for line in stream:
        if not line.strip():  # empty line...
            continue  # ignore it!
        level, stream = line.split(None, 1)  # split on log level and log data
        message_enc = base64.b64decode(stream.encode("latin-1"))  # decode the stream
        iv = message_enc[:AES.block_size]  # grab the IV from the beginning
        # decrypt the stream
        message = AES.new(key, AES.MODE_CBC, iv).decrypt(message_enc[AES.block_size:])
        padding = ord(message[-1])  # get the padding value; Python 3.x: message[-1]
        if message[-padding:] != chr(padding) * padding:  # verify the padding
            # on Python 3.x:     bytes([padding]) * padding
            raise ValueError("Invalid padding encountered.")
        # Python 3.x: decode the message: message[:-padding].decode("utf-8")
        yield "{} {}".format(level, message[:-padding])   # yield the decrypted value
然后,您可以在任何可以更改日志格式化程序的地方使用它,即:

import sys
import logging

# lets get the root logger
root = logging.getLogger()
root.handlers = []  # blank out the existing handlers

# create a new handler, file handler instead of stdout is perfectly fine
handler = logging.StreamHandler(stream=sys.stdout)
# now lets get to business
handler.setFormatter(EncryptedLogFormatter("Whatever key/pass you'd like to use",
                                           "[%(levelname)s] %(message)s"))
# lets add it to the root logger so it gets called by the rest of the app automatically
root.addHandler(handler)

# And lets see what happens:
logging.warn("Sensitive stuff, hide me!")
# [WARNING] NDKeIav5G5DtbaSPB4Y/DR3+GZ9IwmXKzVTua1tTuDZ7uMwxBAKTXgIi0lam2dOQ
# YMMV, the IV is random so every block will be different every time
当然,您可以加密级别、时间戳,以及
logging.LogRecord
中的任何内容,并且可以输出您喜欢的任何格式。当需要阅读日志时,您只需要做相反的事情——请参阅中的示例

更新:根据请求,下面介绍如何进行“反向”(即解密加密日志)。首先,让我们创建一些用于测试的日志条目(继续前面的内容):

如果格式保持不变(
[%(levelname)s]%(message)s
),这将导致类似日志的结果(当然,由于随机IV,它将始终不同):

然后,您可以将其用作常规生成器来解密日志,例如:

logs = ["[WARNING] LQMLkbx3YF7ra3e5ZLRj3p1mi2dwCOJe/GMfo2Xg8BBSZMDmZO75rrgoiy/6kqjf",
        "[INFO] D+ehnsq1kWQi61AsLOBkqglXla7jgc2myPFaCGcfCRe6drk9ZmNl+M3UkKPWkDiU",
        "[DEBUG] +rHEHkM2YHJCkIL+YwWI4FNqg6AOXfaBLRyhZpk8/fQxrXLWxcGoGxh9A2vO+7bq"]

for line in log_decryptor("Whatever key/pass you'd like to use", logs):
    print(line)

# [WARNING] Lorem ipsum dolor sit amet.
# [INFO] Consectetur adipiscing elit.
# [DEBUG] Sed do eiusmod tempor.
或者,如果您已将日志设置为流式传输到文件,则可以直接解密该文件,如下所示:

with open("path/to/encrypted.log", "r") as f:
    for line in log_decryptor("Whatever key/pass you'd like to use", f):
        print(line)  # or write to a 'decrypted.log' for a more persistent solution

您将不得不考虑如何区分二进制日志文件中的多个“行”,因为<代码> \n>代码>也可以出现在单个日志消息的密文的中间。我可以使用base64而不是二进制。python3不存在
setFormatter
,有其他替代方法吗?@MasoudR.-在Python3.x上也应该可以-根据官方Python文档,基本结构没有任何变化:。我刚刚仔细检查了一下,效果很好。你会遇到什么样的错误?谢谢,我错过了日志记录。它可以在Python3上正常工作,但必须对
EncryptedLogFormatter
中的消息进行编码。是否也可以添加解密方法?
logs = ["[WARNING] LQMLkbx3YF7ra3e5ZLRj3p1mi2dwCOJe/GMfo2Xg8BBSZMDmZO75rrgoiy/6kqjf",
        "[INFO] D+ehnsq1kWQi61AsLOBkqglXla7jgc2myPFaCGcfCRe6drk9ZmNl+M3UkKPWkDiU",
        "[DEBUG] +rHEHkM2YHJCkIL+YwWI4FNqg6AOXfaBLRyhZpk8/fQxrXLWxcGoGxh9A2vO+7bq"]

for line in log_decryptor("Whatever key/pass you'd like to use", logs):
    print(line)

# [WARNING] Lorem ipsum dolor sit amet.
# [INFO] Consectetur adipiscing elit.
# [DEBUG] Sed do eiusmod tempor.
with open("path/to/encrypted.log", "r") as f:
    for line in log_decryptor("Whatever key/pass you'd like to use", f):
        print(line)  # or write to a 'decrypted.log' for a more persistent solution