Python pycrypto加密/解密,解密时丢失部分加密字符串

Python pycrypto加密/解密,解密时丢失部分加密字符串,python,encryption,pycrypto,Python,Encryption,Pycrypto,我正在尝试用python中的pycrypto加密/解密。在大多数情况下,工作都很顺利,但我在解密数据时遇到了一个奇怪的问题。我尝试对一些JPG进行加密/解密以进行测试,尽管它们加密/解密没有问题,但解密的文件无法打开/损坏。为了找到问题,我保存了一个文本文件,其中有一个类似于“测试这个文件的完整性”之类的随机句子,它只有在“…完整性”之类的内容之后才能正确解密,完整性之前的所有内容仍然是乱码。我对AES不太了解,但我假设这是一个编码/解码或填充错误 这是我的密码: #encryption iv

我正在尝试用python中的pycrypto加密/解密。在大多数情况下,工作都很顺利,但我在解密数据时遇到了一个奇怪的问题。我尝试对一些JPG进行加密/解密以进行测试,尽管它们加密/解密没有问题,但解密的文件无法打开/损坏。为了找到问题,我保存了一个文本文件,其中有一个类似于“测试这个文件的完整性”之类的随机句子,它只有在“…完整性”之类的内容之后才能正确解密,完整性之前的所有内容仍然是乱码。我对AES不太了解,但我假设这是一个编码/解码或填充错误

这是我的密码:

#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:])
        

      您正在分别为加密和解密生成一个新的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)。用那些来代替


      我没有亲自测试过这段代码,所以它可能无法正常工作。

      您正在生成一个新的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许可下)。如果您想解除此帖子与您帐户的关联,请参阅。