TripleDES Encryption in C # and PHP doesn't work the same (PKCS7, ECB)?

I spent a couple of hours trying to figure it out, but I just can't get it to work. I have a c # encryption procedure that I need to map in php. I can’t change the C # version, this is not an option (the third party is solid in this).

Here's the 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);
}

Here is the best I've come up with 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);
}

As far as I know, I am correctly handling the PKCS7 add-on on the PHP side. I'm not sure what else to try.

One note: C # happens on windows, and PHP on linux, not sure if this should matter.

+3
source share
4 answers

The fill length in your version of PHP depends on the length of the password. This is not true. It should be based on the length of your message.

strlen($password) strlen($data).


, mcrypt 24- . Triple DES DES , 8- , DES K 1, K 2 K 3 > . . . - K 3 K 1. ( DES) , K 1= K 2= K 3.

"", 16- 3DES : K 3= K 1. .NET , mcrypt ; K 3= 0. mcrypt 24- .

MD5 8 $key $key, 24- mcrypt_encrypt().

+10

, , . http://sanity-free.com/131/triple_des_between_php_and_csharp.html

:

    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);
    }
+1

encoding.getBytes, Bytes UTF8...

0

, # IV. , , , msdn :

Property IV is automatically set to a new random value whenever you create a new instance of one of the SymmetricAlgorithm classes or when you manually call the GenerateIV method.

It looks like you are using IV in the PHP version . You can try not to supply IV and hope that the C # version also uses zeros.

Edit: It looks like for ECB, IV is ignored.

You may also need to encode the key, as in C #, using utf8-encode

-1
source

Source: https://habr.com/ru/post/1785523/


All Articles