我正在实现一个可以加密和解密二维码内容的python包。我制作了一个名为 的模块rsa_module.py
,用于对消息进行加密和解密,如下所示:
from Crypto.PublicKey import RSA
from Crypto.Random import get_random_bytes
from Crypto.Cipher import AES, PKCS1_OAEP
import os
def generate_keys(secret_code):
key = RSA.generate(2048)
encrypted_key = key.exportKey(passphrase=secret_code, pkcs=8,
protection="scryptAndAES128-CBC")
output_directory=os.path.dirname(os.path.abspath(__file__))+'/Keys/'
if(os.path.exists(output_directory)):
# Save encrypted private key
file_out = open(output_directory + "/rsa_private_key.pem", "wb")
file_out.write(encrypted_key)
# Save public key
file_out = open(output_directory + "/rsa_public_key.pem", "wb")
file_out.write(key.publickey().exportKey())
else:
os.mkdir(output_directory)
# Save encrypted private key
file_out = open(output_directory + "/rsa_private_key.pem", "wb")
file_out.write(encrypted_key)
# Save public key
file_out = open(output_directory + "/rsa_public_key.pem", "wb")
file_out.write(key.publickey().exportKey())
def encrypt(message):
output_directory=os.path.dirname(os.path.abspath(__file__))+'/Keys/'
with open('encrypted_data.txt', 'wb') as out_file:
recipient_key = RSA.import_key(
open(output_directory + '/rsa_public_key.pem').read())
session_key = get_random_bytes(16)
cipher_rsa = PKCS1_OAEP.new(recipient_key)
out_file.write(cipher_rsa.encrypt(session_key))
cipher_aes = AES.new(session_key, AES.MODE_EAX)
encoded = message.encode("latin-1")
data = encoded
ciphertext, tag = cipher_aes.encrypt_and_digest(data)
out_file.write(cipher_aes.nonce)
out_file.write(tag)
out_file.write(ciphertext)
with open('encrypted_data.txt', 'rb') as fobj:
output = [l for l in fobj.readlines()]
os.remove('encrypted_data.txt')
return output
def decrypt(encrypted_message, secret_code):
code = secret_code
output_directory=os.path.dirname(os.path.abspath(__file__))+'/Keys/'
with open('encrypted_data.txt', 'wb') as temp_file:
for item in (encrypted_message):
temp_file.write(item)
with open('encrypted_data.txt', 'rb') as fobj:
private_key = RSA.import_key(
open(output_directory + '/rsa_private_key.pem').read(),
passphrase=code)
enc_session_key, nonce, tag, ciphertext = [ fobj.read(x)
for x in (private_key.size_in_bytes(),
16, 16, -1) ]
cipher_rsa = PKCS1_OAEP.new(private_key)
session_key = cipher_rsa.decrypt(enc_session_key)
cipher_aes = AES.new(session_key, AES.MODE_EAX, nonce)
data = cipher_aes.decrypt_and_verify(ciphertext, tag)
os.remove('encrypted_data.txt')
return data.decode('utf8')
def main():
generate_keys('secret one')
encrypted = encrypt('blah blah blah blo')
#encrypt_file('blah blah blah blo')
print('Encryption Complete!')
print('Decrypting message now....')
print(encrypted)
print(decrypt(encrypted, 'secret one'))
#decrypt_file('secret one')
if __name__=='__main__': main()
如果我运行此脚本,则消息将被成功加密和解密。但是,当我在另一个模块中使用相同的函数时,从 QR 码中解密消息,我得到一个错误。该二维码解密模型名称为decrypt_qr.py
,代码如下:
from qrtools import qrtools
from PIL import Image
import zbarlight
import os
from rsa_module import decrypt as de
def decrypt(file_name, password):
keys_directory=os.path.dirname(os.path.abspath(__file__))+'/Keys/'
private_key_path = keys_directory + '/rsa_private_key.pem'
if(os.path.exists(private_key_path)):
output_directory=os.path.dirname(os.path.abspath(__file__))+'/Output/'
file_path = output_directory + file_name + '.PNG'
with open(file_path, 'rb') as image_file:
image = Image.open(image_file)
image.load()
codes = zbarlight.scan_codes('qrcode', image)
decoded_result=codes[0].decode('utf8')
print(codes[0].decode('utf8'))
return de(decoded_result, password)
else:
print('No Public key available. Generate Public key and Private key first.')
return None
def main():
print(decrypt('my-qr','My secret'))
if __name__=='__main__': main()
如果我运行decrypt_qr.py
,我会收到以下错误:
Traceback (most recent call last):
File "decrypt_qr.py", line 28, in <module>
if __name__=='__main__': main()
File "decrypt_qr.py", line 26, in main
print(decrypt('my-qr','My secret'))
File "decrypt_qr.py", line 20, in decrypt
return de(decoded_result, password)
File "/Users/king/Documents/pyWorkspace/Encrypted_QR_Code_Using_AES/rsa_module.py", line 93, in decrypt
temp_file.write(item)
TypeError: a bytes-like object is required, not 'str'
但是,如果我rsa_module.py
只使用传递的消息运行它,那么它确实会正确解密。谁能建议我哪里出错了?
名为 的加密模块encrypt_qr.py
如下:
from generate_qr import make_qr_and_save
from rsa_module import encrypt as en
from rsa_module import generate_keys
import os
def encrypt(message, filename, password, size=3):
generate_keys(password)
keys_directory=os.path.dirname(os.path.abspath(__file__))+'/Keys/'
public_key_path = keys_directory + '/rsa_public_key.pem'
if(os.path.exists(public_key_path)):
encrypted_message = en(message)
print('\n')
print(encrypted_message)
make_qr_and_save(encrypted_message, filename, size)
else:
print('No Public key available. Generate Public key and Private key first.')
return None
def main():
encrypt('Buzz off!','my-qr','My secret')
if __name__=='__main__': main()
如果我运行encrypt_qr.py
脚本,则 qr 代码会正确生成并包含加密的字节流,然后在解密脚本 ( decrypt_qr.py
) 中使用。