Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/316.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 使用Powershell从PyCrypto解密AES CBC数据_Python_Powershell_Encryption_Aes_Pycrypto - Fatal编程技术网

Python 使用Powershell从PyCrypto解密AES CBC数据

Python 使用Powershell从PyCrypto解密AES CBC数据,python,powershell,encryption,aes,pycrypto,Python,Powershell,Encryption,Aes,Pycrypto,我正在从事一个项目,在这个项目中,我将使用PyCrypto的AES模块对一串数据进行加密,然后使用Powershell对其进行解密 我已经编写了一个简单的加密函数来完成这里需要的工作: import base64 from Crypto import Random from Crypto.Cipher import AES key = "SuperSecret" #Insecure and just for testing plaintext = "Secret message please

我正在从事一个项目,在这个项目中,我将使用PyCrypto的AES模块对一串数据进行加密,然后使用Powershell对其进行解密

我已经编写了一个简单的加密函数来完成这里需要的工作:

import base64

from Crypto import Random
from Crypto.Cipher import AES

key = "SuperSecret" #Insecure and just for testing
plaintext = "Secret message please don't look"

BS = 16
pad = lambda s: s + (BS - len(s) % BS) * chr(BS - len(s) % BS)

def padKey(s): #Pad key to 32 bytes for AES256
    return (s * (int(32/len(s))+1))[:32]

class AESCipher:

    def __init__(self, key):
        self.key = key

    def encrypt(self, raw):
        raw = pad(raw)
        iv = Random.new().read( AES.block_size )
        cipher = AES.new( self.key, AES.MODE_CBC, iv )
        return base64.b64encode( iv + cipher.encrypt( raw ) )

paddedKey = padKey(key)
cipher = AESCipher(paddedKey)

encrypted = str(cipher.encrypt(plaintext))
encrypted = encrypted[2:-1]

print("Key:", paddedKey)
print("Plaintext:",plaintext)
print("Encrypted and B64:",encrypted)
我在使用Powershell解密和解码输出时遇到一些问题,需要一些帮助。我在网上找到了一个简单的解密脚本,但输出都是垃圾:

function Create-AesManagedObject($key, $IV) {
    $aesManaged = New-Object "System.Security.Cryptography.AesManaged"
    $aesManaged.Mode = [System.Security.Cryptography.CipherMode]::CBC
    $aesManaged.Padding = [System.Security.Cryptography.PaddingMode]::Zeros
    $aesManaged.BlockSize = 128
    $aesManaged.KeySize = 256
    if ($IV) {
        if ($IV.getType().Name -eq "String") {
            $aesManaged.IV = [System.Convert]::FromBase64String($IV)
        }
        else {
            $aesManaged.IV = $IV
        }
    }
    if ($key) {
        if ($key.getType().Name -eq "String") {
            $aesManaged.Key = [System.Convert]::FromBase64String($key)
        }
        else {
            $aesManaged.Key = $key
        }
    }
    $aesManaged
}

function Decrypt-String($key, $encryptedStringWithIV) {
    $bytes = [System.Convert]::FromBase64String($encryptedStringWithIV)
    $IV = $bytes[0..15]
    $aesManaged = Create-AesManagedObject $key $IV
    $decryptor = $aesManaged.CreateDecryptor();
    $unencryptedData = $decryptor.TransformFinalBlock($bytes, 16, $bytes.Length - 16);
    $aesManaged.Dispose()
    [System.Text.Encoding]::UTF8.GetString($unencryptedData).Trim([char]0)
}
样本输出:

PS C:\> Decrypt-String 'SuperSecretSuperSecretSuperSecre' $encryptedString
���H�'G zM۞� �i�ZtCI���H~N�GG��A�Pc��aF��`)��GS�N�2{�[.

相关:

在Python代码中,以下内容完全没有必要,应该删除:

encrypted = str(cipher.encrypt(plaintext))
encrypted = encrypted[2:-1]
在PowerShell代码中,需要使用
PKCS7
而不是
zero
作为填充


在PowerShell代码中,您不会在任何地方实现零填充键。这是必需的(我不知道如果没有它,您如何使其工作)。

在Python代码中,以下内容完全没有必要,应该删除:

encrypted = str(cipher.encrypt(plaintext))
encrypted = encrypted[2:-1]
在PowerShell代码中,需要使用
PKCS7
而不是
zero
作为填充


在PowerShell代码中,您不会在任何地方实现零填充键。这是必需的(我不知道没有它你怎么能让它工作)。

用解决方案结束这一切(感谢@Maarten和@t.m.adam)。这个问题有两个方面。首先,需要以Base64格式将密钥传递给Powershell,并且需要将填充移到PKCS7。最终代码如下:

Python加密:

import base64

from Crypto import Random
from Crypto.Cipher import AES

key = "SuperSecret" #Insecure and just for testing
plaintext = "Secret message please don't look"

BS = 16
pad = lambda s: s + (BS - len(s) % BS) * chr(BS - len(s) % BS)

def padKey(s): #Pad key to 32 bytes for AES256
    return (s * (int(32/len(s))+1))[:32]

class AESCipher:

    def __init__(self, key):
        self.key = key

    def encrypt(self, raw):
        raw = pad(raw)
        iv = Random.new().read( AES.block_size )
        cipher = AES.new( self.key, AES.MODE_CBC, iv )
        return base64.b64encode( iv + cipher.encrypt( raw ) )

paddedKey = padKey(key)
cipher = AESCipher(paddedKey)

encrypted = str(cipher.encrypt(plaintext))
encrypted = encrypted[2:-1]

print("Key:", base64.b64encode(paddedKey))
print("Plaintext:",plaintext)
print("Encrypted and B64:",encrypted)
Powershell解密:

function Create-AesManagedObject($key, $IV) {
    $aesManaged = New-Object "System.Security.Cryptography.AesManaged"
    $aesManaged.Mode = [System.Security.Cryptography.CipherMode]::CBC
    $aesManaged.Padding = [System.Security.Cryptography.PaddingMode]::PKCS7
    $aesManaged.BlockSize = 128
    $aesManaged.KeySize = 256
    if ($IV) {
        if ($IV.getType().Name -eq "String") {
            $aesManaged.IV = [System.Convert]::FromBase64String($IV)
        }
        else {
            $aesManaged.IV = $IV
        }
    }
    if ($key) {
        if ($key.getType().Name -eq "String") {
            $aesManaged.Key = [System.Convert]::FromBase64String($key)
        }
        else {
            $aesManaged.Key = $key
        }
    }
    $aesManaged
}

function Decrypt-String($key, $encryptedStringWithIV) {
    $bytes = [System.Convert]::FromBase64String($encryptedStringWithIV)
    $IV = $bytes[0..15]
    $aesManaged = Create-AesManagedObject $key $IV
    $decryptor = $aesManaged.CreateDecryptor();
    $unencryptedData = $decryptor.TransformFinalBlock($bytes, 16, $bytes.Length - 16);
    $aesManaged.Dispose()
    [System.Text.Encoding]::UTF8.GetString($unencryptedData).Trim([char]0)
}
用法:

PS C:> $key = 'U3VwZXJTZWNyZXRTdXBlclNlY3JldFN1cGVyU2VjcmU='
PS C:> $encryptedString = 'Opgtr8XEcvkcYT5UzsFjZR4Wt5DI++fU4Gm0dTM/22m+xyObjP162rFphIS/xkS4I7ErJfshwI7T4X1MNz
wMog=='
PS C:> Decrypt-String $key $encryptedString
Secret message please don't look

用解决方案结束这一切(感谢@Maarten和@t.m.adam)。这个问题有两个方面。首先,需要以Base64格式将密钥传递给Powershell,并且需要将填充移到PKCS7。最终代码如下:

Python加密:

import base64

from Crypto import Random
from Crypto.Cipher import AES

key = "SuperSecret" #Insecure and just for testing
plaintext = "Secret message please don't look"

BS = 16
pad = lambda s: s + (BS - len(s) % BS) * chr(BS - len(s) % BS)

def padKey(s): #Pad key to 32 bytes for AES256
    return (s * (int(32/len(s))+1))[:32]

class AESCipher:

    def __init__(self, key):
        self.key = key

    def encrypt(self, raw):
        raw = pad(raw)
        iv = Random.new().read( AES.block_size )
        cipher = AES.new( self.key, AES.MODE_CBC, iv )
        return base64.b64encode( iv + cipher.encrypt( raw ) )

paddedKey = padKey(key)
cipher = AESCipher(paddedKey)

encrypted = str(cipher.encrypt(plaintext))
encrypted = encrypted[2:-1]

print("Key:", base64.b64encode(paddedKey))
print("Plaintext:",plaintext)
print("Encrypted and B64:",encrypted)
Powershell解密:

function Create-AesManagedObject($key, $IV) {
    $aesManaged = New-Object "System.Security.Cryptography.AesManaged"
    $aesManaged.Mode = [System.Security.Cryptography.CipherMode]::CBC
    $aesManaged.Padding = [System.Security.Cryptography.PaddingMode]::PKCS7
    $aesManaged.BlockSize = 128
    $aesManaged.KeySize = 256
    if ($IV) {
        if ($IV.getType().Name -eq "String") {
            $aesManaged.IV = [System.Convert]::FromBase64String($IV)
        }
        else {
            $aesManaged.IV = $IV
        }
    }
    if ($key) {
        if ($key.getType().Name -eq "String") {
            $aesManaged.Key = [System.Convert]::FromBase64String($key)
        }
        else {
            $aesManaged.Key = $key
        }
    }
    $aesManaged
}

function Decrypt-String($key, $encryptedStringWithIV) {
    $bytes = [System.Convert]::FromBase64String($encryptedStringWithIV)
    $IV = $bytes[0..15]
    $aesManaged = Create-AesManagedObject $key $IV
    $decryptor = $aesManaged.CreateDecryptor();
    $unencryptedData = $decryptor.TransformFinalBlock($bytes, 16, $bytes.Length - 16);
    $aesManaged.Dispose()
    [System.Text.Encoding]::UTF8.GetString($unencryptedData).Trim([char]0)
}
用法:

PS C:> $key = 'U3VwZXJTZWNyZXRTdXBlclNlY3JldFN1cGVyU2VjcmU='
PS C:> $encryptedString = 'Opgtr8XEcvkcYT5UzsFjZR4Wt5DI++fU4Gm0dTM/22m+xyObjP162rFphIS/xkS4I7ErJfshwI7T4X1MNz
wMog=='
PS C:> Decrypt-String $key $encryptedString
Secret message please don't look

嘿谢谢你的回复。该片段只是为了删除一些Python格式,因为B64字符串的输出方式类似于
b'
。至于PKCS7填充,它抛出了一个新错误,
“填充无效,无法删除。”
。我也不确定你所说的键填充是什么意思。我没有在Python代码中编写执行零填充的
padKey
方法。我也不知道如何在PowerShell代码中加载/生成密钥。
padKey
函数只是重复密钥,直到其长度达到32字节(即“secret”->“secretse”)。密钥通过命令行参数与已编码和加密的数据一起传递给Powershell decrypter函数。只要您100%确定它是正确的,否则您可能会像现在这样回收垃圾。以十六进制打印Python和PowerShell代码的密钥,并进行比较!密钥通常不包含字符,顺便说一句,您应该使用基于密码的加密(PBE)。因此,随着@t.m.adam注释的出现,更改填充似乎已经做到了这一点!谢谢你的帮助!嘿谢谢你的回复。该片段只是为了删除一些Python格式,因为B64字符串的输出方式类似于
b'
。至于PKCS7填充,它抛出了一个新错误,
“填充无效,无法删除。”
。我也不确定你所说的键填充是什么意思。我没有在Python代码中编写执行零填充的
padKey
方法。我也不知道如何在PowerShell代码中加载/生成密钥。
padKey
函数只是重复密钥,直到其长度达到32字节(即“secret”->“secretse”)。密钥通过命令行参数与已编码和加密的数据一起传递给Powershell decrypter函数。只要您100%确定它是正确的,否则您可能会像现在这样回收垃圾。以十六进制打印Python和PowerShell代码的密钥,并进行比较!密钥通常不包含字符,顺便说一句,您应该使用基于密码的加密(PBE)。因此,随着@t.m.adam注释的出现,更改填充似乎已经做到了这一点!谢谢你的帮助!请参见这一行:
if($key.getType().Name-eq“String”){
。因此,base64对键(String)进行编码或者使用字节。嘿!我刚刚尝试将B64编码的密钥传递到Powershell函数,但输出仍然被破坏。抱歉,我已经使用
'U3VwZXJTZWNyZXRTdXBlclNlY3JldFN1cGVyU2VjcmU='
作为密钥测试了您的Powershell代码,结果是Python的
明文
字符串(由于不同的填充方法,加上一些垃圾-请参阅Maarten的)这是有效的!非常感谢!请参阅这一行:
if($key.getType().Name-eq“String”){
。因此,base64或者对键(String)进行编码或者使用字节。嘿!我刚刚尝试将B64编码的密钥传递到Powershell函数,但输出仍然被破坏。抱歉,我已经使用
'U3VwZXJTZWNyZXRTdXBlclNlY3JldFN1cGVyU2VjcmU='
作为密钥测试了您的Powershell代码,结果是Python的
明文
字符串(加上一些垃圾,因为不同的填充方法-见Maarten的)这很有效!非常感谢!