You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用PyCrypto AES CBC加密的数据无法用PowerShell正常解密求助

解决Python AES加密后PowerShell解密乱码的问题

我最近在做一个项目,需要用Python的PyCrypto库AES模块加密字符串,再通过PowerShell解密。我已经写了加密函数,但用PowerShell解密时输出全是乱码,折腾了半天没搞定,来求助大家。

我的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:", paddedKey)
print("Plaintext:",plaintext)
print("Encrypted and B64:",encrypted)

遇到的问题

加密过程是正常的,但我用网上找到的PowerShell解密脚本运行时,输出全是乱码:

我的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{�[.

问题分析与解决方法

对比两边的实现后,发现了几个关键的不匹配点,调整后就能正常解密:

  1. 填充方式不一致:Python用的是PKCS#7填充(也就是pad函数的逻辑),但PowerShell脚本里设置的是PaddingMode::Zeros,这是导致乱码的核心原因。
  2. Key的处理逻辑错误:Python里是将key字符串重复截断为32字节后直接使用(默认转成UTF-8字节),但PowerShell里却把key当成Base64字符串来解码,完全不符合预期。
  3. 解密后字符串处理错误:因为用了PKCS#7填充,解密时.NET的TransformFinalBlock会自动移除填充字节,不需要手动Trim掉0字符。

修改后的PowerShell解密代码

function Create-AesManagedObject($key, $IV) {
    $aesManaged = New-Object "System.Security.Cryptography.AesManaged"
    $aesManaged.Mode = [System.Security.Cryptography.CipherMode]::CBC
    # 改为PKCS7填充,和Python的实现对齐
    $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") {
            # 将key字符串直接转成UTF-8字节,而非Base64解码
            $aesManaged.Key = [System.Text.Encoding]::UTF8.GetBytes($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()
    # PKCS7填充已自动处理,直接转换为字符串即可
    [System.Text.Encoding]::UTF8.GetString($unencryptedData)
}

现在再运行解密命令,就能正确得到原明文Secret message please don't look了!

内容的提问来源于stack exchange,提问作者dosgatos

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 09:37:20