2017-06-10 31 views
0

私はロギングを持つpythonスクリプトを持っています。今私はpycryptoを使ってAESでログを暗号化したいと思う。Pythonロギングモジュールを暗号化

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.b64encode(aes.encrypt('#logging text#'))を使用します。それを行う最も不動産の方法は何ですか?

+0

バイナリログファイルで複数の "行"を区別する方法について考える必要があります。なぜなら、 '\ n 'は単一のログメッセージの暗号文の中央に現れることがあるからです。 –

+0

ありがとう、ありがとう。バイナリの代わりにbase64を使うことができます。 – stepuncius

答えて

2

単なるデータの転送よりも暗号化がもう少しあります。独自のログフォーマッタを作成し、ルートフォーマッタとして設定することをお勧めします。つまり、どこのアプリケーションからログを取っても、コードによって制御されない部分であっても、常に暗号化レイヤーを通過します。だから、何かのように:あなたはログフォーマッタを変更することができますどこ

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

class EncryptedLogFormatter(logging.Formatter): 

    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 
      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 # on Python 3.x use: 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 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からほとんど何でも、あなたが好きなフォーマットを出力することができます。あなたのログを読む時が来たら、その逆をするだけです - 例をthis answerで見てください。