2016-07-13 19 views
0

Ich entwickle eine Integration in C#, die Office365-Verteilerlisten zu Sendy (sendy.co), in PHP geschrieben, synchronisiert.PHP openssl_encrypt C# Implementierung

In der PHP-Anwendung werden einige IDs verschlüsselt und ich möchte das gleiche in C# erreichen, so dass ich über ihre API kommunizieren kann, ohne die 'geheime' ID nachschlagen zu müssen.

Dies ist der Code in PHP (ich das Passwort ersetzt) ​​in ihrer Anwendung, die diese IDs berechnet:

$encrypted = openssl_encrypt($in, 'AES-256-CBC', 'API_KEY', 0, 'SECRET_PASSWORD'); 
$encrypted = str_replace('/', '892', $encrypted); 
$encrypted = str_replace('+', '763', $encrypted); 
$encrypted = str_replace('=', '', $encrypted); 

ich dieses ‚Problem‘ wand durch den PHP-Skript irgendwo Hosting und es von meiner C# .NET-Anwendung aufrufen , aber ich möchte es opensource machen, also möchte ich, dass es in die Anwendung integriert wird.

Ich nehme an, ich müsste mit .NET AesCryptoServiceProvider starten, aber ich bin nicht in der Lage, es richtig zu machen (ich bekomme Ausnahmen über die Schlüssellänge und so Zeug).

Bisher habe ich versucht, dies:

public static string Execute() 
    { 
     // openssl_encrypt (string $data , string $method , string $password [, int $options = 0 [, string $iv = "" ]]) 
     var aes = new AesCryptoServiceProvider(); 
     aes.KeySize = 256; 

     // Fixed password in code 
     aes.Key = Encoding.UTF8.GetBytes("FIXED PASSWORD"); 
     // API = IV 
     aes.IV = Encoding.UTF8.GetBytes("SENDY API KEY"); 

     aes.Mode = CipherMode.CBC; 

     // Trying to encrypt "36" in this case 
     byte[] src = Encoding.Unicode.GetBytes("36"); 

     // Actual encryption 
     using (var encrypt = aes.CreateEncryptor()) 
     { 
      byte[] dest = encrypt.TransformFinalBlock(src, 0, src.Length); 

      // Convert byte array to Base64 strings 
      return Convert.ToBase64String(dest); 
     } 
    } 

Doch diese eine Ausnahme auslöst sagen die IV nicht die Blockgröße des Algorithmus entspricht.

Ich nehme an, die openssl_encrypt-Methode in PHP-Derivaten die tatsächliche IV aus der angegebenen API-KEY in der Probe (so der Parameter $ password), aber ich kann nicht viel Dokumentation finden, um das gleiche in C# zu erreichen .

+0

Die Codes haben wir die Codes benötigt. Bei SO geht es nicht darum, deinen Code zu schreiben, sondern darum, dir mit Code zu helfen. Fügen Sie Ihren versuchten Code zusammen mit detaillierten Problemen und Debugging-Ausgaben hinzu. – zaph

+0

Es gibt bessere Möglichkeiten, um mit störenden Zeichen in Base64 umzugehen, was Sie haben, wird brechen. Sowohl '892' als auch '763' können gültige Base64-Sequenzen sein. In der Regel wird nur Base64 mit einer URL codiert, falls erforderlich. Die Verwendung einer konstanten iv ist eine schlechte Idee und unsicher. – zaph

+0

Ja, ich kann verstehen, dass der PHP-Code keine gute Übung ist, aber ich habe ihn nicht geschrieben und es ist nicht meine Anwendung, ich muss nur das Gleiche in PHP erreichen. Ich löschte meinen "versuchenden" Code, ich versuche es erneut und aktualisiere meine Frage mit meinem versuchten Code, sorry :) –

Antwort

0

Die Größe des iv muss gleich der Blockgröße sein, die für AES 16-Byte ist, "SENDY API KEY" ist nur 13-Byte.

Die iv sollte einen anderen zufälligen Wert für jede Verschlüsselung, nur vor die verschlüsselten Daten für die Verwendung während der Entschlüsselung.

Als nächstes haben Sie eine Schlüsselgröße von 256-Bits angegeben, aber der Schlüssel "FIXED PASSWORD" ist nur 14-Bytes, machen Sie die gleichen, 128, 192 oder 256 Bits (16, 24 oder 32 Bytes). Es besteht keine Notwendigkeit, einen Schlüssel über 128 Bits zu verwenden.

Ein Passwort sollte nicht direkt für einen Schlüssel verwendet werden, der Schlüssel sollte aus dem Passwort mit einer Funktion wie PBKFD2 abgeleitet werden.

AES ist eine Blockchiffre und es ist. Die Eingabe muss ein Vielfaches der Blocklänge sein. Um dies zu erreichen, wird das Auffüllen der Eingabe benötigt. Normalerweise wird PKCS # 7 (bisher PKCS # 5) verwendet. Dies ist wahrscheinlich der Standard für OpenSSL. Die Verschlüsselung/Entschlüsselung sollte diese Auffüllung automatisch hinzufügen/entfernen. Dies bedeutet jedoch, dass die Länge der verschlüsselten Daten von 1 Byte bis 16 Byte länger ist als die der Eingabe. z.B. Wenn Sie "36" verschlüsseln, beträgt die Ausgabelänge 16 Byte.

bekommen das alles zusammen kann richtig schwierig sein, korrekt zu erhalten, sollten Sie eine Gesamtlösung wie RNCryptor-php oder defuse