使用 Powershell 从 PyCrypto 解密 AES CBC 数据
Decrypting AES CBC data from PyCrypto with Powershell
我正在做一个项目,我将使用 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{�[.
相关:Using PowerShell to decrypt a Python encrypted String
在 Python 代码中,以下完全没有必要,应该删除:
encrypted = str(cipher.encrypt(plaintext))
encrypted = encrypted[2:-1]
在您的 PowerShell 代码中,您需要使用 PKCS7
而不是 Zeros
作为填充。
在 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
我正在做一个项目,我将使用 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{�[.
相关:Using PowerShell to decrypt a Python encrypted String
在 Python 代码中,以下完全没有必要,应该删除:
encrypted = str(cipher.encrypt(plaintext))
encrypted = encrypted[2:-1]
在您的 PowerShell 代码中,您需要使用 PKCS7
而不是 Zeros
作为填充。
在 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