1

I have been given a set of codes from a third party that need encrypting/decrypting however the sample encryption code they gave me was in C# and I am primarily a front-end PHP developer.

I have set-up a slimmed down working example of the code I was provided here using the sample key of A818163DD5E0DE87.

public static byte[] HexStringToByteArray(String hex)
{
int NumberChars = hex.Length;
byte[] bytes = new byte[NumberChars / 2];
for (int i = 0; i < NumberChars; i += 2) {
bytes[i / 2] = Convert.ToByte(hex.Substring(i, 2), 16);
}
return bytes;
}

// Convers a byte array to a HEX string
public static string ByteArrayToHexString(byte[] bytes)
{
StringBuilder hexString = new StringBuilder(bytes.Length * 2);
for (int i = 0; i < bytes.Length; i++)
{
hexString.Append(bytes[i].ToString("X2"));
}
return hexString.ToString();
}

public static byte[] Encrypt()
{
string plainText = "GROW06BP";
DESCryptoServiceProvider desCrypto = new DESCryptoServiceProvider();
desCrypto.Key = HexStringToByteArray("A818163DD5E0DE87");
desCrypto.IV = HexStringToByteArray("A818163DD5E0DE87");
desCrypto.Mode = CipherMode.CBC;
desCrypto.Padding = PaddingMode.Zeros;
// Create a buffer for the Plain Text using ASCIIEncoding
byte[] plaintextBytes = (new ASCIIEncoding()).GetBytes(plainText);
// Create a memory stream for the encrypted bytes
MemoryStream msEncrypt = new MemoryStream();
// Create a CryptoStream using the memory stream and the passed Algorithm
CryptoStream csEncrypt = new CryptoStream(msEncrypt, desCrypto.CreateEncryptor(), CryptoStreamMode.Write);
// Write the plaintext to the CryptoStream
csEncrypt.Write(plaintextBytes, 0, plaintextBytes.Length);
// Close the CryptoStream
csEncrypt.Close();
// Read the Encrypted bytes into our buffer
byte[] encryptedTextBytes = msEncrypt.ToArray();
// Close the Memory Stream
msEncrypt.Close();
// And return the encrypted buffer
return encryptedTextBytes;
}

I have scoured stack overflow and other sites in an attempt to replicate this in PHP but nothing comes close to the correct output. I'm also confused by which cipher I am meant to be using and how to convert the key and iv to match the C# example. Below is what I have attempted so far.

$key = unpack('H*', "A818163DD5E0DE87");
$key = "A818163DD5E0DE87";
$iv = $key;
$plaintext = "GROW06BP";
$ciphertext = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $key, $plaintext,MCRYPT_MODE_CBC, $iv);
echo base64_encode($ciphertext);

Any help would be appreciated.

1
  • 2
    In C# you're using DES but in PHP you're using Rijndael (AES). They are different encryption algorithms! Commented May 26, 2016 at 7:22

2 Answers 2

1

Things you need to consider:

  • DESCryptoServiceProvider -> mcrypt_module_open('des'
  • desCrypto.Mode = CipherMode.CBC; -> mcrypt_module_open(...,..., 'cbc',
  • key,iv and the cipher output are "treated" with HexStringToByteArray(), pack('H*) can undo that

So, given the output of the .net fiddle (7860D97E56DA6A40) that leads to

<?php
$msgHex = '7860D97E56DA6A40'; 
$keyHex = 'A818163DD5E0DE87';
$ivHex = 'A818163DD5E0DE87';  // really? invalidates the use-case of an iv :-/

// this reverts the effect of HexStringToByteArray() 
$msg = pack('H*', $msgHex);
$key = pack('H*', $keyHex);
$iv = pack('H*', $ivHex);

// add error handing !
$module = mcrypt_module_open('des', '', 'cbc', '');
mcrypt_generic_init($module, $key, $iv);
$plaintext = mdecrypt_generic($module, $msg);
mcrypt_generic_deinit($module);

echo $plaintext;

output: GROW06BP

Sign up to request clarification or add additional context in comments.

1 Comment

Thank you very much VolkerK, this allows me to successfully decrypt the codes. I don't think I would have ever got this as I didn't come across those functions at all when searching for this.
0

As I've already mentioned in my comment, you're using the wrong algorithm in your PHP code since it's Rijndael. What you should use is MCRYPT_DES.

$key = "A818163DD5E0DE87";
// Here you need pack instead of unpack
$packKey = pack("H*",$key);
// you should use the key as the initialization vector
// use something like mcrypt_create_iv to generate an IV
$iv = $packKey;
$plaintext = "GROW06BP";
// replaced MCRYPT_RIJNDAEL_128 with MCRYPT_DES
$ciphertext = mcrypt_encrypt(MCRYPT_DES, $packKey, $plaintext,MCRYPT_MODE_CBC, $iv);
echo base64_encode($ciphertext);

This will produce the same output as the C# code

1 Comment

Thanks for all your help Nasreddine. Your code looks great to me but seems to output a different result to the C# code, which is where a lot of my confusion came from with this.

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.