使用Python中使用PBKDF2构建的密码解密AES-256-CBC密码

使用Python中使用PBKDF2构建的密码解密AES-256-CBC密码,python,encryption,Python,Encryption,我有一个加密的会话密钥,我需要用python解密,但我真的不知道该怎么做 我得到了密码短语、salt和hmac密钥。我需要解码的字符串是base64编码的,解码时它是管道描述的密钥和到期日期(会话密钥+管道分隔符+日期时间) 会话密钥“使用AES-256-CBC密码和使用PBKDF2-基于密码的密钥派生函数2构建的密码进行加密。然后使用HMAC密钥对加密的有效负载进行签名。” 我将如何使用Python实现这一点?这方面最好的图书馆是什么 以下是我的许多尝试之一(根据的评论编辑): 在发布的代码中

我有一个加密的会话密钥,我需要用python解密,但我真的不知道该怎么做

我得到了密码短语、salt和hmac密钥。我需要解码的字符串是base64编码的,解码时它是管道描述的密钥和到期日期(会话密钥+管道分隔符+日期时间)

会话密钥“使用AES-256-CBC密码和使用PBKDF2-基于密码的密钥派生函数2构建的密码进行加密。然后使用HMAC密钥对加密的有效负载进行签名。”

我将如何使用Python实现这一点?这方面最好的图书馆是什么

以下是我的许多尝试之一(根据的评论编辑):


在发布的代码中,加密和解密是混淆的。因为需要解密

以下代码段使用PBKDF2生成32字节的密钥,该密钥用于加密明文,并使用AES-256-CBC解密生成的密文:

from base64 import b64encode
import hashlib
import pyaes
import os

plaintext = 'The quick brown fox jumps over the lazy dog'
password = b'password provided'
salt = b'Salt provided'
iterationCount = 1000

# Create random 16 bytes IV 
iv = os.urandom(16)

# Create 32 bytes key
key = hashlib.pbkdf2_hmac('sha256', password, salt, iterationCount)

# Encryption with AES-256-CBC
encrypter = pyaes.Encrypter(pyaes.AESModeOfOperationCBC(key, iv))
ciphertext = encrypter.feed(plaintext.encode('utf8'))
ciphertext += encrypter.feed()

# Decryption with AES-256-CBC
decrypter = pyaes.Decrypter(pyaes.AESModeOfOperationCBC(key, iv))
decryptedData = decrypter.feed(ciphertext)
decryptedData += decrypter.feed()

# Display results
def printData(text, data):
    print(text + " (hex):    " + data.hex()) 
    print(text + " (Base64): " + b64encode(data).decode('utf8') + "\n")

printData("16 bytes IV", iv)
printData("32 bytes Key", key)
printData("Ciphertext", ciphertext)
print("Decrypted data (UTF-8): " + decryptedData.decode('utf8') + "\n")
注:

  • 在您的描述中,没有提到摘要和迭代计数。在发布的代码SHA256中,使用
    1000
    计数。这两个参数都很关键,即对于解密,必须使用与加密相同的参数

    此外,IV通常在加密期间生成(而不是在解密期间),并与密文一起传递

  • 根据您的描述PBKDF2,应用AES-CBC和HMAC。通常在该星座中,生成具有PBKDF2的密钥,用于加密明文(此处使用AES-CBC)并生成MAC以认证消息

    请注意,发布的代码只提供解密,而不提供身份验证。另外,我的代码片段没有身份验证

  • 各个算法可以以不同的方式组合。讨论了一种可能的变体。尽管这可能是一个评级很高的变体,但这并不意味着底层加密必须坚持使用它

    链接变量将生成的32字节密钥拆分为两个16字节密钥,用于加密和身份验证。通过这种方式执行AES-128加密,这与您描述的AES-256加密不同

    简而言之:要成功执行解密和身份验证,必须知道某些信息。除了密钥生成之外,还包括IV生成、MAC生成(哪些数据用于生成MAC)、数据串联(密文顺序、IV和MAC)等


在发布的代码中,加密和解密是混淆的。因为需要解密

以下代码段使用PBKDF2生成32字节的密钥,该密钥用于加密明文,并使用AES-256-CBC解密生成的密文:

from base64 import b64encode
import hashlib
import pyaes
import os

plaintext = 'The quick brown fox jumps over the lazy dog'
password = b'password provided'
salt = b'Salt provided'
iterationCount = 1000

# Create random 16 bytes IV 
iv = os.urandom(16)

# Create 32 bytes key
key = hashlib.pbkdf2_hmac('sha256', password, salt, iterationCount)

# Encryption with AES-256-CBC
encrypter = pyaes.Encrypter(pyaes.AESModeOfOperationCBC(key, iv))
ciphertext = encrypter.feed(plaintext.encode('utf8'))
ciphertext += encrypter.feed()

# Decryption with AES-256-CBC
decrypter = pyaes.Decrypter(pyaes.AESModeOfOperationCBC(key, iv))
decryptedData = decrypter.feed(ciphertext)
decryptedData += decrypter.feed()

# Display results
def printData(text, data):
    print(text + " (hex):    " + data.hex()) 
    print(text + " (Base64): " + b64encode(data).decode('utf8') + "\n")

printData("16 bytes IV", iv)
printData("32 bytes Key", key)
printData("Ciphertext", ciphertext)
print("Decrypted data (UTF-8): " + decryptedData.decode('utf8') + "\n")
注:

  • 在您的描述中,没有提到摘要和迭代计数。在发布的代码SHA256中,使用
    1000
    计数。这两个参数都很关键,即对于解密,必须使用与加密相同的参数

    此外,IV通常在加密期间生成(而不是在解密期间),并与密文一起传递

  • 根据您的描述PBKDF2,应用AES-CBC和HMAC。通常在该星座中,生成具有PBKDF2的密钥,用于加密明文(此处使用AES-CBC)并生成MAC以认证消息

    请注意,发布的代码只提供解密,而不提供身份验证。另外,我的代码片段没有身份验证

  • 各个算法可以以不同的方式组合。讨论了一种可能的变体。尽管这可能是一个评级很高的变体,但这并不意味着底层加密必须坚持使用它

    链接变量将生成的32字节密钥拆分为两个16字节密钥,用于加密和身份验证。通过这种方式执行AES-128加密,这与您描述的AES-256加密不同

    简而言之:要成功执行解密和身份验证,必须知道某些信息。除了密钥生成之外,还包括IV生成、MAC生成(哪些数据用于生成MAC)、数据串联(密文顺序、IV和MAC)等


对于pyaes和AEC-CBC,如果密文长度超过1个块(16个字节),则应使用
decrypter.feed()
。有关其他Python加密库,请参见例如…@Topaco-非常感谢。我仍然不太清楚,但我已经根据您的评论更新了我的问题。对于pyaes和AEC-CBC,如果密文长度超过1个块(16字节),您应该使用
decrypter.feed()
,并且。有关其他Python加密库,请参见例如…@Topaco-非常感谢。我仍然不太清楚,但我已经根据你的评论更新了我的问题。