4

I have the following .Net code which takes two inputs. 1) A 128 bit base 64 encoded key and 2) the userid. It outputs the AES encrypted token. I need the php equivalent of the same code, but dont know which corresponding php classes are to be used for RNGCryptoServiceProvider,RijndaelManaged,ICryptoTransform,MemoryStream and CryptoStream. Im stuck so any help regarding this would be really appreciated.

using System;
using System.Text;
using System.IO;
using System.Security.Cryptography;

class AESToken
{
  [STAThread]
  static int Main(string[] args)
  {
    if (args.Length != 2)
    {
      Console.WriteLine("Usage: AESToken key userId\n");
      Console.WriteLine("key Specifies 128-bit AES key base64 encoded supplied by MediaNet to the partner");
      Console.WriteLine("userId specifies the unique id");
      return -1;
    }

    string key = args[0];
    string userId = args[1];

    StringBuilder sb = new StringBuilder();
    // This example code uses the magic string “CAMB2B”. The implementer
    // must use the appropriate magic string for the web services API.
    sb.Append("CAMB2B");
    sb.Append(args[1]);     // userId
    sb.Append('|');  // pipe char
    sb.Append(System.DateTime.UtcNow.ToString("yyyy-MM-dd HH:mm:ssUTC")); //timestamp
    Byte[] payload = Encoding.ASCII.GetBytes(sb.ToString());

    byte[] salt = new Byte[16];  // 16 bytes of random salt
    RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider();
    rng.GetBytes(salt);  // the plaintext is 16 bytes of salt followed by the payload.

    byte[] plaintext = new byte[salt.Length + payload.Length];
    salt.CopyTo(plaintext, 0);
    payload.CopyTo(plaintext, salt.Length);

    // the AES cryptor: 128-bit key, 128-bit block size, CBC mode
    RijndaelManaged cryptor = new RijndaelManaged();
    cryptor.KeySize = 128;
    cryptor.BlockSize = 128;
    cryptor.Mode = CipherMode.CBC;
    cryptor.GenerateIV();
    cryptor.Key = Convert.FromBase64String(args[0]); // the key
    byte[] iv = cryptor.IV;   // the IV.

    // do the encryption
    ICryptoTransform encryptor = cryptor.CreateEncryptor(cryptor.Key, iv);
    MemoryStream ms = new MemoryStream();
    CryptoStream cs = new CryptoStream(ms, encryptor, CryptoStreamMode.Write);
    cs.Write(plaintext, 0, plaintext.Length);
    cs.FlushFinalBlock();
    byte[] ciphertext = ms.ToArray();
    ms.Close();
    cs.Close();

    // build the token
    byte[] tokenBytes = new byte[iv.Length + ciphertext.Length];
    iv.CopyTo(tokenBytes, 0);
    ciphertext.CopyTo(tokenBytes, iv.Length);
    string token = Convert.ToBase64String(tokenBytes);
    Console.WriteLine(token);
    return 0;
   }
}

Please help. Thank You.

0

3 Answers 3

2

We are also trying figure out the same C# in PHP. You can post your code without the key.

First approach:

    // Open the cipher:
    // Using Rijndael 128 in CBC mode.
    $m = mcrypt_module_open('rijndael-128', '', 'cbc', ''); 
    $iv = mcrypt_create_iv(mcrypt_enc_get_iv_size($m), MCRYPT_RAND); 

    // Initialize the encryption:
    mcrypt_generic_init($m, (base64_decode($key_)), $iv);

    // Encrypt the data:
    $cryptext = mcrypt_generic($m, $plain_text);

    //echo "IV SIZE ".mcrypt_enc_get_iv_size($m);
    $tx2 =  base64_encode($iv.$cipherText);

    // Close the encryption handler:
    mcrypt_generic_deinit($m);

    // Close the cipher:
    mcrypt_module_close($m);

Second approach for initialization:

    $m = mcrypt_module_open(MCRYPT_RIJNDAEL_128, '', MCRYPT_MODE_CBC, '');
    $iv_size = mcrypt_enc_get_iv_size($m); 
    $iv = mcrypt_create_iv(mcrypt_enc_get_iv_size($m), MCRYPT_RAND); 
    $key128 = base64_decode($key_);

    // Encrypt the data:
    $cryptext = mcrypt_generic($m, $plain_text);

    $tx2 =  base64_encode($iv.$cipherText);

    // Close the encryption handler:
    mcrypt_generic_deinit($m); 
Sign up to request clarification or add additional context in comments.

Comments

1

You would use the mcrypt library in PHP to implement the same functionality.

Comments

1

You can see the following code that works:

<?php

class UserData
{
    public $email;
    public $name;
    public $expires;
}

class Application 
{
    private $api_key = "<private_key>";
    private $app_key = "appkey";

    public function run()
    {
       $user = new UserData();
       $date = new DateTime(null, new DateTimeZone('UTC'));
       $date->modify('+5 minute');
       $user->expires = $date->format('c');
       $user->email = "[email protected]";
       $user->name = "PHP5 Example";
       $encrypted_data = $this->encryptUserData($user);
       // Example login URL
       printf("http://<domain>/multipass?sso=%s", $encrypted_data);
    }

    private function encryptUserData($user_data)
    {
        $app_key = $this->app_key;
        $api_key = $this->api_key;
        $json = json_encode($user_data);

        $salted = $api_key . $app_key;
        $saltedHash = substr(sha1($salted, true), 0, 16);

        $pad = 16 - (strlen($json) % 16);
        $data = $json . (str_repeat(chr($pad), $pad));

        if (!function_exists('mcrypt_encrypt'))
            throw new Exception('Mcrypt extension is not installed for PHP.');
        $aes = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $saltedHash, $data, MCRYPT_MODE_CBC, str_repeat("\0", 16));

        $b64token = base64_encode($aes);
        $b64token = rtrim(str_replace(array('+', '/'), array('-', '_'), $b64token), '=');

        return $b64token;
    }
}

$app = new Application();
$app->run();

?>

I hope it will be helpful for you. Thanks.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.