Python pycrypto加密/解密,解密时丢失部分加密字符串
我正在尝试用python中的pycrypto加密/解密。在大多数情况下,工作都很顺利,但我在解密数据时遇到了一个奇怪的问题。我尝试对一些JPG进行加密/解密以进行测试,尽管它们加密/解密没有问题,但解密的文件无法打开/损坏。为了找到问题,我保存了一个文本文件,其中有一个类似于“测试这个文件的完整性”之类的随机句子,它只有在“…完整性”之类的内容之后才能正确解密,完整性之前的所有内容仍然是乱码。我对AES不太了解,但我假设这是一个编码/解码或填充错误 这是我的密码:Python pycrypto加密/解密,解密时丢失部分加密字符串,python,encryption,pycrypto,Python,Encryption,Pycrypto,我正在尝试用python中的pycrypto加密/解密。在大多数情况下,工作都很顺利,但我在解密数据时遇到了一个奇怪的问题。我尝试对一些JPG进行加密/解密以进行测试,尽管它们加密/解密没有问题,但解密的文件无法打开/损坏。为了找到问题,我保存了一个文本文件,其中有一个类似于“测试这个文件的完整性”之类的随机句子,它只有在“…完整性”之类的内容之后才能正确解密,完整性之前的所有内容仍然是乱码。我对AES不太了解,但我假设这是一个编码/解码或填充错误 这是我的密码: #encryption iv
#encryption
iv = Random.new().read( AES.block_size)
filePath = input("Path to file for encryption: ")
selFile = open(filePath, 'rb')
getBytes = bytes(selFile.read())
encPW = input("Enter password: ")
hashpw = hashlib.sha256(encPW.encode('UTF-8').digest())
destination = input("Destination path for encrypted file: ")
aes = AES.new(hashpw, AES.Mode_CFB, iv)
encFile = base65.b64encode(aes.encrypt(getBytes))
writetofile = open(destination, 'wb')
writetofile.write(encFile)
writetofile.close()
print("Encryption successful")
#Decryption
iv = Random.new().read( AES.block_size)
filePath = input("Path to file for decryption: ")
selFile = open(filePath, 'rb')
getBytes = bytes(selFile.read())
decPW = input("Enter password: ")
hashdecpw = hashlib.sha256(encPW.encode('UTF-8').digest())
destination = input("Destination path for decrypted file: ")
aes = AES.new(hashdecpw, AES.Mode_CFB, iv)
decFile = aes.decrypt(getBytes)
writetofile = open(destination, 'wb')
writetofile.write(decFile)
writetofile.close()
print("Decryption successful")
你知道是什么原因导致第一个字符丢失,并阻止我正确加密/解密文件吗?你至少有三个问题:
- 您可能指的是
,而不是hashlib.sha256(encPW.encode('UTF-8')).digest()
(右括号位置错误)hashlib.sha256(encPW.encode('UTF-8').digest())
- 在将密文写入文件之前,您正在使用Base64对其进行编码。在解密之前从文件中读回后,您忘记对其进行解码。例如:
getBytes = base64.b64decode(bytes(selFile.read()))
- 这是一个大问题:在解密过程中,您需要与用于加密的完全相同的IV。IV不是秘密,但对于使用相同密钥进行的每一次加密,它都必须是唯一的。通常,IV写在密文前面,然后读回进行解密
#encryption encFile = base64.b64encode(iv + aes.encrypt(getBytes)) #decryption getBytes = base64.b64decode(bytes(selFile.read())) iv = getBytes[:16] aes = AES.new(hashdecpw, AES.Mode_CFB, iv) decFile = aes.decrypt(getBytes[16:])
- 您可能指的是
,而不是hashlib.sha256(encPW.encode('UTF-8')).digest()
(右括号位置错误)hashlib.sha256(encPW.encode('UTF-8').digest())
- 在将密文写入文件之前,您正在使用Base64对其进行编码。在解密之前从文件中读回后,您忘记对其进行解码。例如:
getBytes = base64.b64decode(bytes(selFile.read()))
- 这是一个大问题:在解密过程中,您需要与用于加密的完全相同的IV。IV不是秘密,但对于使用相同密钥进行的每一次加密,它都必须是唯一的。通常,IV写在密文前面,然后读回进行解密
#encryption encFile = base64.b64encode(iv + aes.encrypt(getBytes)) #decryption getBytes = base64.b64decode(bytes(selFile.read())) iv = getBytes[:16] aes = AES.new(hashdecpw, AES.Mode_CFB, iv) decFile = aes.decrypt(getBytes[16:])
- 您至少有三个问题:
def encrypt(inpath, outpath, password):
iv = Random.new().read(AES.block_size)
with open(inpath, "rb") as f:
contents = f.read()
# A context manager automatically calls f.close()
key = pbkdf2.crypt(password, "")
# See notes
aes = AES.new(key, AES.Mode_CFB, iv)
encrypted = aes.encrypt(contents)
with open(outpath, "wb") as f:
f.write(iv + b":")
f.write(encrypted)
print("Encryption successful")
def decrypt(inpath, outpath, password):
with open(inpath, "rb") as f:
contents = f.read()
iv, encrypted = contents.split(b":")
key = pbkdf2.crypt(password, "")
aes = AES.new(key, AES.Mode_CFB, iv)
decrypted = aes.decrypt(contents)
with open(outpath, "wb") as f:
f.write(decrypted)
print("Decryption successful")
一些注意事项:
- IV并不意味着是秘密的,因此它可以随机生成一次,然后写入一个文件以供以后解密(如本例所示)
- 哈希算法不足以派生密钥,这就是为什么有称为密钥派生算法的特殊工具(如python中的PBKDF2)。用那些来代替
我没有亲自测试过这段代码,所以它可能无法正常工作。您正在生成一个新的IV,分别用于加密和解密,这会产生这样的问题。以下是我的建议:
def encrypt(inpath, outpath, password):
iv = Random.new().read(AES.block_size)
with open(inpath, "rb") as f:
contents = f.read()
# A context manager automatically calls f.close()
key = pbkdf2.crypt(password, "")
# See notes
aes = AES.new(key, AES.Mode_CFB, iv)
encrypted = aes.encrypt(contents)
with open(outpath, "wb") as f:
f.write(iv + b":")
f.write(encrypted)
print("Encryption successful")
def decrypt(inpath, outpath, password):
with open(inpath, "rb") as f:
contents = f.read()
iv, encrypted = contents.split(b":")
key = pbkdf2.crypt(password, "")
aes = AES.new(key, AES.Mode_CFB, iv)
decrypted = aes.decrypt(contents)
with open(outpath, "wb") as f:
f.write(decrypted)
print("Decryption successful")
一些注意事项:
- IV并不意味着是秘密的,因此它可以随机生成一次,然后写入一个文件以供以后解密(如本例所示)
- 哈希算法不足以派生密钥,这就是为什么有称为密钥派生算法的特殊工具(如python中的PBKDF2)。用那些来代替
我自己还没有测试过这段代码,所以它可能无法正常工作。密码散列的好技巧。我错过了。太好了,两个答案都完全正确。我只使用hash算法进行测试,现在这些问题已经解决了,我将实现PBKDF2。不管怎么说,这不是批评,只是学术性的,而是优秀的观点。感谢您的回答和帮助!密码散列的好技巧。我错过了。太好了,两个答案都完全正确。我只使用hash算法进行测试,现在这些问题已经解决了,我将实现PBKDF2。不管怎么说,这不是批评,只是学术性的,而是优秀的观点。感谢您的回答和帮助!几乎不重要,但是
str.encode()
自动假定UTF-8:)谢谢Artjom,在这些更改之后,一切都正常工作了。看来静脉注射确实是我错过的好机会。感谢您的帮助虽然不重要,但是str.encode()
自动假定为UTF-8:)谢谢Artjom在这些更改之后,一切都正常工作了。看来静脉注射确实是我错过的好机会。感谢您的帮助请不要破坏您的帖子。请不要破坏您的帖子。一旦您发布了一个问题,您就已经将内容授权给了Stack Overflow社区(在CC by SA许可下)。如果您想解除此帖子与您的帐户的关联,请参阅。请不要破坏您的帖子。请不要破坏您的帖子。一旦您发布了一个问题,您就已经将内容授权给了Stack Overflow社区(在CC by SA许可下)。如果您想解除此帖子与您帐户的关联,请参阅。