1
votes

I got an encrypting function written in PHP which encrypts my data, and a decrypt function in C# which decrypts it and prints on screen(I'm developing a game in Unity engine). So the problem is, if the data string is long it won't decrypt the last part of it... I'm using AES 256 encryption with key

php function:

$username = "Name"
$id = 1;
$email = "[email protected]"

$data = $username . "\n" . $id . "\n" . $email;

$key = "my 256 bit key"; //32 bytes
function aes256Encrypt($key, $data) {
    if(32 !== strlen($key)) $key = hash('SHA256', $key, true);
    $padding = 16 - (strlen($data) % 16);
    $data .= str_repeat(chr($padding), $padding);
    return mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $key, $data, MCRYPT_MODE_CBC, str_repeat("\0", 16));
}

echo base64_encode(aes256Encrypt($key, $data));

This is my C# full code which prints the decrypted string on game screen:

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

public class session : MonoBehaviour {

    private string sessionURL = "http://localhost/xampp/game/session.php";

    void Start () 
    {
        StartCoroutine(GetSession());
    }

    IEnumerator GetSession()
    {
        gameObject.guiText.text = "Loading Session";
        WWW ses_get = new WWW(sessionURL);
        yield return ses_get;

        string key = "my 256 bit key";
        string base64_ciphered_text = ses_get.text;
        String sestext = Decrypt(base64_ciphered_text, key);

        if (ses_get.error != null)
        {
            print("There was an error getting the session: " + ses_get.error);
        }
        else
        {
            guiText.richText = true;
            guiText.text = sestext;
        }
    }


    public String Decrypt(String text, String key)
    {
        //decode cipher text from base64
        byte[] cipher = Convert.FromBase64String(text);
        //get key bytes
        byte[] btkey = Encoding.ASCII.GetBytes(key);

        //init AES 256
        RijndaelManaged aes256 = new RijndaelManaged();
        aes256.Mode = CipherMode.ECB;
        aes256.Padding = PaddingMode.Zeros;

        //decrypt
        ICryptoTransform decryptor = aes256.CreateDecryptor(btkey, null);
        MemoryStream ms = new MemoryStream(cipher);
        CryptoStream cs = new CryptoStream(ms, decryptor, CryptoStreamMode.Read);

        byte[] plain = new byte[cipher.Length];
        int decryptcount = cs.Read(plain, 0, plain.Length);

        ms.Close();
        cs.Close();

        //return plaintext in String
        return Encoding.UTF8.GetString(plain, 0, decryptcount);
    }

}

Anyone got an idea?

One example of what I mean: $data: http://puu.sh/6BkU4.png output on screen: http://puu.sh/6BkTF.jpg

1
Looks like you're padding with zeroes in C#, and padding with an arbitrary character in PHP as well...Marc B
You should consider using a standard protocol which has been designed for this. Try TLS. Anything simpler is simply not secure.ntoskrnl

1 Answers

0
votes

You're using CBC-mode in PHP and ECB in C# so after the first block things will go wrong. You need to use the same mode in both cases.