Mein Ziel ist es, in AES eine Zeichenfolge in PowerShell verschlüsseln zu können, sie an ein UNIX-System mit verfügbarem Python zu senden und die Zeichenfolge wieder in reinen Text zu entschlüsseln. Ich würde auch gern in der Lage sein, das Gegenteil zu tun. Ich bin kein Krypto-Typ oder ein Powershell/Python-Programmierer, aber das ist, was ich in der Lage gewesen mit dem Code zu tun, so weit:AES-Verschlüsselung in PowerShell und Python
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 Encrypt-String($key, $unencryptedString) {
$bytes = [System.Text.Encoding]::UTF8.GetBytes($unencryptedString)
$aesManaged = Create-AesManagedObject $key $IV
$encryptor = $aesManaged.CreateEncryptor()
$encryptedData = $encryptor.TransformFinalBlock($bytes, 0, $bytes.Length);
[byte[]] $fullData = $aesManaged.IV + $encryptedData
$aesManaged.Dispose()
[System.Convert]::ToBase64String($fullData)
}
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)
}
# key passphrase is a 16 byte string that is used to create the AES key.
$key_passphrase = "MypassphraseKey1"
# base64 encode the key. The resulting key should be exactly 44 characters (43 characters with a single = of padding) (256 bits)
$Bytes = [System.Text.Encoding]::Ascii.GetBytes($key_passphrase)
$key =[Convert]::ToBase64String($Bytes)
# init is used to create the IV
$init = "This is an IV123"
# converts init to a byte array (e.g. T = 84, h = 104) and then sha1 hash it
$IV = (new-Object Security.Cryptography.SHA1Managed).ComputeHash([Text.Encoding]::UTF8.GetBytes($init))[0..15]
write-output "IV is equal to $IV"
write-output "AES key is $key"
$unencryptedString = "testing"
$encryptedString = Encrypt-String $key $unencryptedString
$backToPlainText = Decrypt-String $key $encryptedString
write-output "Unencrypted string: $unencryptedString"
write-output "Encrypted string: $encryptedString"
write-output "Unencrytped string: $backToPlainText"
Der Powershell-Skript scheint gut für die Verschlüsselung und Entschlüsselung zu arbeiten. Für die Python-Seite kann ich den gleichen AES-Schlüsselwert definieren, da er nur base64-kodiert für die Passphrase meines Schlüssels ist. Allerdings erhalte ich bei der Ausführung nicht den gleichen verschlüsselten Wert der Zeichenfolge (z. B. PowerShell-Ausgaben UXKWIhtaUgFOvN13bvA4tx4 + 2Hjkv4v6I1G3Xfl6zp0 = und Python gibt BOJ3Ox4fJxR + jFZ0CBQ25Q == aus). Ich glaube, dass diese übereinstimmen müssten, um entschlüsseln zu können, aber ich könnte mich irren. Ich weiß, dass das Setzen einer statischen IV und des Schlüssels es unsicher macht, aber ich bin dazu bereit, um plattformübergreifend verschlüsseln und entschlüsseln zu können (es sei denn, es gibt eine bessere Methode, AES zu verwenden). Jede Hilfe wäre willkommen.
Python-Code
import base64, array
import Crypto
import Crypto.Random
from Crypto.Cipher import AES
def pad_data(data):
if len(data) % 16 == 0:
return data
databytes = bytearray(data)
padding_required = 15 - (len(databytes) % 16)
databytes.extend(b'\x80')
databytes.extend(b'\x00' * padding_required)
return bytes(databytes)
def unpad_data(data):
if not data:
return data
data = data.rstrip(b'\x00')
if data[-1] == 128: # b'\x80'[0]:
return data[:-1]
else:
return data
def encrypt(key, iv, data):
aes = AES.new(key, AES.MODE_CBC, iv)
data = pad_data(data)
return aes.encrypt(data)
def decrypt(key, iv, data):
aes = AES.new(key, AES.MODE_CBC, iv)
data = aes.decrypt(data)
return unpad_data(data)
def test_crypto():
key = "MypassphraseKey1"
# found using the debugger in the PowerShell ISE to get the value byte value which was converted to hex
iv = "\x51\x72\x96\x22\x1b\x5a\x52\x01\x4e\xbc\xdd\x77\x6e\xf0\x38\xb7"
msg = b"testing"
# hex value of IV in powershell script is 51 72 96 22 1b 5a 52 01 4e bc dd 77 6e f0 38 b7
print("Value of IV: " + iv)
# base64 encode key
b64key = base64.b64encode(key)
print("AES key encoded: " + b64key)
code = encrypt(key, iv, msg)
# convert encrypted string to base64
b64encoded = base64.b64encode(code)
print("Encrypted string: " + b64encoded)
decoded = decrypt(key, iv, code)
print("Decoded: " + decoded)
if __name__ == '__main__':
test_crypto()
Danke, ich schätze die Hilfe. Ich habe das Python-Skript basierend auf einigen Ihrer Vorschläge angepasst und die statische IV entfernt. Ich weiß, dass das Python-Skript in der Lage ist, die Powershell-Ausgabe zu dekodieren und umgekehrt. Ich werde auch an der Umsetzung der anderen Vorschläge arbeiten. –
@MichaelWilliams Ich denke, dass Sie die Antwort auffrischen sollten: Wenn Sie es akzeptierten, bedeutet es wahrscheinlich, dass es eine Stimme verdient. – xverges
Sorry, neu zu Stack-Überlauf. Ich glaube, es sollte jetzt aufgewertet werden. –