PyCryptoDome cipher.encrypt 将空白文本保存到加密文件
PyCryptoDome cipher.encrypt saving blank text to encrypted file
我在加密 accountfile 路径下的文件内容时遇到很多问题。
加密确实有效,因为解密成功输出了将路径保存到文件的版本的帐户文件的路径。代码运行成功,没有错误,但保存的加密文件在加密时最终为空白。如何让ptext的内容加密成功?
def encrypt_account(path, filename, accountfile):
c_file = PurePath(path).parent / (PurePath(filename).parent.name + "c.txt")
file3 = open(c_file, 'rb')
byteskey = file3.read(32)
file3.close()
ckey = bytes(byteskey)
cipher = AES.new(ckey, AES.MODE_CBC)
ptext = open(str(accountfile)).read()# this is the account file
ciphertext = cipher.encrypt(pad(bytes(ptext, "utf-8"), AES.block_size))
with open(str(path.parent / accountfile.stem) + ".enc", 'wb')as c_file:
c_file.write(cipher.iv)
c_file.write(ciphertext)
#c_file.close()
#os.remove(accountfile)
这是一个有效的例子,但是请不要将它用于任何敏感的事情,因为它不安全。
正确使用密码学原语是困难;你应该改用 higher-level 比你我更聪明的人编写并证明在正确使用时是安全的食谱。我对 Python 的建议是 Fernet。
除此之外,您可以编写一些秘密数据并生成一个密钥,然后 运行 脚本并取回您的秘密数据:
$ echo "Very secret data" > secret.txt
$ dd if=/dev/urandom bs=1 count=32 > key.dat
32 bytes transferred
$ python so64569401.py
b'Very secret data\n'
但是,如前所述,这是 不 安全的,因为数据未经过身份验证;密文可以被篡改,你不会知道数据不是你放回的。例如,如果我删除第一个加密调用,然后修改加密文件中的单个字节和 运行 脚本再次:
$ hexf secret.txt.enc
$ python so64569401.py
b'Very secRet data\n'
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad, unpad
def read_key(filename) -> bytes:
with open(filename, "rb") as f:
key = f.read(32)
assert len(key) == 32
return key
def encrypt_file(filename: str, key: bytes) -> str:
with open(filename, "rb") as f:
data = f.read()
cipher = AES.new(key, AES.MODE_CBC)
cipher_data = cipher.encrypt(pad(data, AES.block_size))
encrypted_filename = filename + ".enc"
with open(encrypted_filename, "wb") as f:
f.write(cipher.iv)
f.write(cipher_data)
return encrypted_filename
def decrypt_file(filename: str, key: bytes) -> bytes:
with open(filename, "rb") as f:
iv = f.read(AES.block_size)
cipher_data = f.read()
cipher = AES.new(key, AES.MODE_CBC, iv=iv)
return unpad(cipher.decrypt(cipher_data), AES.block_size)
def main():
key = read_key("key.dat")
encrypted_filename = encrypt_file("secret.txt", key)
decrypted_data = decrypt_file(encrypted_filename, key)
print(decrypted_data)
if __name__ == "__main__":
main()
我在加密 accountfile 路径下的文件内容时遇到很多问题。 加密确实有效,因为解密成功输出了将路径保存到文件的版本的帐户文件的路径。代码运行成功,没有错误,但保存的加密文件在加密时最终为空白。如何让ptext的内容加密成功?
def encrypt_account(path, filename, accountfile):
c_file = PurePath(path).parent / (PurePath(filename).parent.name + "c.txt")
file3 = open(c_file, 'rb')
byteskey = file3.read(32)
file3.close()
ckey = bytes(byteskey)
cipher = AES.new(ckey, AES.MODE_CBC)
ptext = open(str(accountfile)).read()# this is the account file
ciphertext = cipher.encrypt(pad(bytes(ptext, "utf-8"), AES.block_size))
with open(str(path.parent / accountfile.stem) + ".enc", 'wb')as c_file:
c_file.write(cipher.iv)
c_file.write(ciphertext)
#c_file.close()
#os.remove(accountfile)
这是一个有效的例子,但是请不要将它用于任何敏感的事情,因为它不安全。
正确使用密码学原语是困难;你应该改用 higher-level 比你我更聪明的人编写并证明在正确使用时是安全的食谱。我对 Python 的建议是 Fernet。
除此之外,您可以编写一些秘密数据并生成一个密钥,然后 运行 脚本并取回您的秘密数据:
$ echo "Very secret data" > secret.txt
$ dd if=/dev/urandom bs=1 count=32 > key.dat
32 bytes transferred
$ python so64569401.py
b'Very secret data\n'
但是,如前所述,这是 不 安全的,因为数据未经过身份验证;密文可以被篡改,你不会知道数据不是你放回的。例如,如果我删除第一个加密调用,然后修改加密文件中的单个字节和 运行 脚本再次:
$ hexf secret.txt.enc
$ python so64569401.py
b'Very secRet data\n'
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad, unpad
def read_key(filename) -> bytes:
with open(filename, "rb") as f:
key = f.read(32)
assert len(key) == 32
return key
def encrypt_file(filename: str, key: bytes) -> str:
with open(filename, "rb") as f:
data = f.read()
cipher = AES.new(key, AES.MODE_CBC)
cipher_data = cipher.encrypt(pad(data, AES.block_size))
encrypted_filename = filename + ".enc"
with open(encrypted_filename, "wb") as f:
f.write(cipher.iv)
f.write(cipher_data)
return encrypted_filename
def decrypt_file(filename: str, key: bytes) -> bytes:
with open(filename, "rb") as f:
iv = f.read(AES.block_size)
cipher_data = f.read()
cipher = AES.new(key, AES.MODE_CBC, iv=iv)
return unpad(cipher.decrypt(cipher_data), AES.block_size)
def main():
key = read_key("key.dat")
encrypted_filename = encrypt_file("secret.txt", key)
decrypted_data = decrypt_file(encrypted_filename, key)
print(decrypted_data)
if __name__ == "__main__":
main()