2017-12-16 2 views
1

Ich verwende openssl_encrypt Strings zu verschlüsseln und sieKann nicht mit AES-Verschlüsselung Zeichenfolge entschlüsseln

In PHP

$data = "helloWorld"; 

    $key = 'CefaiNooH4oi6oje'; 
    $iv = 'Choodub8ahd4choo'; 
    $data = openssl_encrypt($data, 'AES-256-CBC', $key, 0, $iv); 

    echo base64_encode($data); 

In Powershell innerhalb Powershell entschlüsseln

$data = "dnQvNEhEczBnQ0F5OEQ4Yi9tOUY4Zz09" 
$data = [System.Convert]::FromBase64String($data) 

$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 
$aesManaged.Key = [system.Text.Encoding]::UTF8.GetBytes("CefaiNooH4oi6oje") 
$aesManaged.IV = [system.Text.Encoding]::UTF8.GetBytes("Choodub8ahd4choo") 
$decryptor = $aesManaged.CreateDecryptor(); 

$clear = $decryptor.TransformFinalBlock($data, 16, $data.Length - 16); 

[System.Text.Encoding]::UTF8.GetString($clear).Trim([char]0) 

Dann bekam ich einen Fehler :

Exception calling "TransformFinalBlock" with "3" argument(s): "The input data is not a complete block." 

Was könnte hier falsch sein?

+0

Diese Antwort kann Ihnen helfen - https://stackoverflow.com/a/19720218/416574 Es erscheint (und ich habe gerade den php-Quellcode überprüft, um dies zu überprüfen), dass der ssl_encrypt den Schlüssel auffüllen wird, um ihn auf die passende Länge zu bringen.Der Schlüssel, den Sie angegeben haben, ist 16 Byte, daher werden dem Schlüssel weitere 16 0 Byte hinzugefügt. Ich kann es immer noch nicht verstehen, um dein Ergebnis zu entschlüsseln, aber ich hoffe, dass der Link hilfreich sein kann. – pstrjds

+0

Ich würde auch empfehlen, von 'TransformFinalBlock' zu wechseln, was eine spezielle Funktion ist, die Sie im letzten Datenblock aufrufen würden. Stattdessen können Sie einfach [TransformBlock] (https://msdn.microsoft.com/en-us/library/system.security.cryptography.icryptotransform.transformblock (v = vs.110) .aspx) – pstrjds

Antwort

1

Edit # 2
In all meiner Aufregung herausgefunden zu haben, warum Müll raus kommen würde, wenn Sie tatsächlich den Entschlüsselungscode zum Laufen bringen, habe ich die Frage, warum Sie die Fehler wurden immer zu beantworten vernachlässigte:
Exception calling "TransformFinalBlock" with "3" argument(s): "The input data is not a complete block."
Das Problem besteht darin, dass Sie einen Datenblock übergeben, der nicht lang genug ist, um ein block zu sein. Wenn Sie die ursprüngliche Zeichenfolge verwenden, die Sie in Bytes konvertiert haben, erhalten Sie ein Array von 24 Byte, aber die Blockgröße beträgt 16 Byte. Sie müssten also ein Array mit einer Länge von 16 haben. Verwenden Sie die korrekte Zeichenfolge vt/4HDs0gCAy8D8b/m9F8g== , erhalten Sie ein Array von 16, was funktionieren wird (obwohl es eine geringfügige Korrektur zu Ihrem Anruf zu TransformFinalBlock gibt, die vorgenommen werden muss, möchten Sie es mit einem Offset von 0 und mit der Länge Ihres Eingabearrays - I aufrufen habe meine Lösung unten aktualisiert, um dies zu zeigen).

End Edit # 2

ich es herausgefunden !!!!

Also, erstes Problem ist hier:

echo base64_encode($data); 

Der $data Wert, den Sie zurück von openssl_encrypt immer schon Base64 codiert, so gibt es keine Notwendigkeit, es wieder zu kodieren. Wenn Sie diese Zeile entfernen, erhalten Sie diese Zeichenfolge zurück vt/4HDs0gCAy8D8b/m9F8g==

(ideone Link sehen) Und für den Fall, dass Sie Beweis dafür, dass das ist, was passiert ist, hier ist ein weiterer ideone Link zeigt, was passiert, wenn Sie die Zeichenfolge aus Base64 konvertieren und Wenn Sie diese Bytes in eine Zeichenfolge konvertieren, erhalten Sie die ursprüngliche Base64-codierte Zeichenfolge, die aus dem Aufruf von openssl_encrypt kam.

Jetzt zum Entschlüsseln Teil (Hinweis, ich werde den Code in C# veröffentlichen, sollte aber ziemlich trivial sein, um in Powershell zu konvertieren, wenn es einen Problemkommentar gibt und ich versuchen werde, zu helfen). Ich würde normalerweise einen Entschlüsseler erstellen und einen Stream verwenden, aber ich wollte mit Ihrem Code passen, also verwende ich die TransformBlock Methode.

string result = null; 
using (var aes = new AesManaged()) 
{ 
    // openssl_encrypt will zero pad a key that is not the correct length 
    var key = Encoding.UTF8.GetBytes("CefaiNooH4oi6oje"); 
    if (key.Length < 32) 
    { 
     var temp = new byte[key.Length + (32 - key.Length % 32)]; 
     Array.Copy(key, temp, key.Length); 
     key = temp; 
    } 
    var iv = Encoding.UTF8.GetBytes("Choodub8ahd4choo"); 

    aes.Mode = CipherMode.CBC; 
    aes.KeySize = 256; 
    aes.Key = key; 
    aes.IV = iv; 
    aes.Padding = PaddingMode.Zeros; 
    var cipher = Convert.FromBase64String("vt/4HDs0gCAy8D8b/m9F8g=="); 
    using (var decryptor = aes.CreateDecryptor()) 
    { 
     var buffer = decryptor.TransformFinalBlock(cipher, 0, cipher.Length); 
     result = Encoding.UTF8.GetString(buffer); 
    } 
} 

bearbeiten Entschlüsselungscode Hinzufügen von Streams mit (wie ich es normalerweise in C#)

using (var aes = new AesManaged()) 
{ 
    // See sample above for setup code, omitted for brevity 
    using (var dest = new MemoryStream()) 
    using (var input = new MemoryStream(cipher)) 
    using (var cs = new CryptoStream(input, aes.CreateDecryptor(), CryptoStreamMode.Read)) 
    { 
     var buffer = new byte[1024]; 
     var read = cs.Read(buffer, 0, buffer.Length); 
     while(read > 0) 
     { 
      dest.Write(buffer, 0, read); 
      read = cs.Read(buffer, 0, buffer.Length); 
     } 
     dest.Flush(); 

     result = Encoding.UTF8.GetString(dest.ToArray()); 
    } 
} 
+0

Es funktioniert, wenn ich geändert habe der Schlüssel zu 32 Bytes und wechselte zu CryptoStream :-P – daisy

Verwandte Themen