Frage

Ich habe jetzt ein paar Stunden damit verbracht, um dies herauszufinden, aber ich kann es einfach nicht an der Arbeit. Ich habe eine C # Verschlüsselungsroutine bekam, dass ich in php übereinstimmen müssen. Ich kann die C # -Version ändern, die nicht eine Option (3rd-Party ist fest auf diesem).

Hier ist der C # -Code:

//In C#
// Console.WriteLine(ApiEncode("testing", "56dsfkj3kj23asdf83kseegflkj43458afdl"));
// Results in: 
//     XvHbR/CsLTo=
public static string ApiEncode(string data, string secret)
{
  byte[] clear;

  var encoding = new UTF8Encoding();
  var md5 = new MD5CryptoServiceProvider();

  byte[] key = md5.ComputeHash(encoding.GetBytes(secret));

  TripleDESCryptoServiceProvider des = new TripleDESCryptoServiceProvider();
  des.Key = key;
  des.Mode = CipherMode.ECB;
  des.Padding = PaddingMode.PKCS7;

  byte[] input = encoding.GetBytes(data);
  try { clear = des.CreateEncryptor().TransformFinalBlock(input, 0, input.Length); }
  finally
  {
    des.Clear();
    md5.Clear();
  }

  return Convert.ToBase64String(clear);
}

Hier ist das Beste, was ich habe kommen mit in PHP:

//In PHP
// echo apiEncode("testing", "56dsfkj3kj23asdf83kseegflkj43458afdl");
// Results in: 
//    5aqvY6q1T54=
function apiEncode($data, $secret)
{    
  //Generate a key from a hash
  $key = md5(utf8_encode($secret), true);
  //Create init vector  
  $iv = mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_3DES, MCRYPT_MODE_ecb), MCRYPT_RAND); 

  //Pad for PKCS7
  $blockSize = mcrypt_get_block_size('tripledes', 'ecb');
  $len = strlen($data);
  $pad = $blockSize - ($len % $blockSize);
  $data .= str_repeat(chr($pad), $pad);

  //Encrypt data
  $encData = mcrypt_encrypt('tripledes', $key, $data, 'ecb'); //, $iv);
  return base64_encode($encData);
}

Nach bestem Wissen und Gewissen, ich bin Umgang mit dem PKCS7 padding richtig auf der PHP-Seite. Ich bin nicht sicher, was anderes zu versuchen.

Eine Sache zu beachten, die C # auf Fenster passiert, und die PHP auf Linux, nicht sicher, das sollten einen Unterschied machen.

War es hilfreich?

Lösung

Die Polsterung Länge in Ihrer PHP-Version auf der Länge des Passworts basiert. Das ist falsch. Es sollte stattdessen auf die Länge Ihrer Nachricht basieren.

Versuchen strlen($password) mit strlen($data) zu ersetzen.


Das zweite Problem ist, dass die mcrypt Bibliothek 24-Byte-Schlüssel erfordert. Triple DES gilt dreimal regelmäßig DES, so dass Sie den 8-Byte-Schlüssel in jeder Runde der DES-K verwendet nennen 1 , K 2 und K 3 . Es gibt verschiedene Möglichkeiten, diese Schlüssel zu wählen. Die sicherste ist drei verschiedene Tasten zur Auswahl. Ein anderer Weg ist K 3 einzustellen gleich K 1 . Die am wenigsten sichere Methode (entspricht DES) ist K 1 = K 2 = K 3 zu machen.

Die meisten Bibliotheken sind "smart" genug, um einen 16-Byte-3DES-Schlüssel als zweite Option oben zu interpretieren: K 3 = K 1 . Die .NET-Implementierung tut dies für Sie, aber die mcrypt Bibliothek ist nicht; Stattdessen ist es Einstellung K 3 = 0. Sie müssen diese selbst beheben, und übergeben mcrypt einen 24-Byte-Schlüssel.

Nach dem MD5-Hash-Berechnung, nehmen die ersten 8 Bytes von $key, und hängen Sie sie an das Ende $key, so dass Sie einen 24-Byte-Wert zu mcrypt_encrypt() zu übergeben.

Andere Tipps

ich eine Lösung gefunden, diesen Link zu überprüfen, können Ihnen helfen. http://sanity-free.com/131/triple_des_between_php_and_csharp.html

Und hier ist die Entschlüsselungsfunktion für alle Fälle:

    public static string Decrypt(string cypherString)
    {

        byte[] key = Encoding.ASCII.GetBytes("icatalogDR0wSS@P6660juht");
        byte[] iv = Encoding.ASCII.GetBytes("iCatalog");
        byte[] data = Convert.FromBase64String(cypherString);
        byte[] enc = new byte[0];
        TripleDES tdes = TripleDES.Create();
        tdes.IV = iv;
        tdes.Key = key;
        tdes.Mode = CipherMode.CBC;
        tdes.Padding = PaddingMode.Zeros;
        ICryptoTransform ict = tdes.CreateDecryptor();
        enc = ict.TransformFinalBlock(data, 0, data.Length);
        return UTF8Encoding.UTF8.GetString(enc, 0, enc.Length);
    }

Hier finden Sie aktuelle encoding.getBytes, müssen Sie den geheimen Schlüssel Bytes von UTF8 ...

Es scheint, die C # Version entspricht nicht der IV . Dies könnte ein Problem sein, wenn Sie nicht wissen, was es ist, weil Msdn sagt:

Die IV-Eigenschaft auf einen neuen Zufallswert automatisch gesetzt, wenn Sie eine neue Instanz eines der SymmetricAlgorithm Klassen erstellen, oder wenn Sie die GenerateIV Methode manuell aufrufen.

Es sieht aus wie in der PHP-Version, erhalten Sie ein IV . Sie könnten versuchen, nicht die IV-Versorgung und die C # -Version hoffen auch Nullen verwendet.

Edit:. Sieht aus wie EZB, die IV ignoriert

Sie können auch wie in der C # -Version zu kodieren, die Schlüssel müssen mit utf8- kodieren

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top