Secure communication PHP (phpseclib) and C# (Unity 3D)

天大地大妈咪最大 提交于 2019-12-01 06:44:23

SOLVED!

By another way - XML key format

Server code:

$rsa = new Crypt_RSA();
$rsa->setEncryptionMode(CRYPT_RSA_ENCRYPTION_PKCS1);
$rsa->setPrivateKeyFormat(CRYPT_RSA_PRIVATE_FORMAT_XML);
$rsa->setPublicKeyFormat(CRYPT_RSA_PUBLIC_FORMAT_XML);

$keys = $rsa->createKey(1024);
extract($keys);
$rsa->loadKey($publickey);
$_SESSION["privatekey"] = $privatekey;
$this->payload->publickey = $publickey;

Generate JSON:

{"publickey":"<RSAKeyValue>\r\n  <Modulus>sCL/O7uUl4T32nUxZhKj1svDG88k4jkGsh/7IiFX/kTbj3mXmtYPLn5xTyLxEt9FxA/aoVxBmh1k7wA7lvcu5z4Avw6+AA/j793iDEhGdfvmXmHxm05xkjYO+LZ449YGDst9DUDO8SDA948Rld+eA187d/nhVPPAmun7RbLXBrs=</Modulus>\r\n  <Exponent>AQAB</Exponent>\r\n</RSAKeyValue>"}

Unity Web Player code:

var N = JSON.Parse (generatedJSON);
var csp = new RSACryptoServiceProvider(1024);
csp.FromXmlString (N ["publickey"]);
var plainTextData = "Hello from Web Player";
var bytesPlainTextData = System.Text.Encoding.Unicode.GetBytes(plainTextData);
var bytesCypherText = csp.Encrypt(bytesPlainTextData, false);
var cypherText = Convert.ToBase64String(bytesCypherText);

And finally Server Decryption:

$rsa = new Crypt_RSA();
$rsa->setEncryptionMode(CRYPT_RSA_ENCRYPTION_PKCS1);
$rsa->setPrivateKeyFormat(CRYPT_RSA_PRIVATE_FORMAT_XML);
$rsa->setPublicKeyFormat(CRYPT_RSA_PUBLIC_FORMAT_XML);

$rsa->loadKey($_SESSION["privatekey"]);
$cypherText= $_POST["cypherText"];
$bytesCipherText = base64_decode($message);
$this->payload->encrypted = $rsa->decrypt($bytesCipherText);

And you get JSON:

{"message":"Hello from Web Player"}

Thanks for perfect phpsec library! Its epic!

I share my example Unity project here. Hoping that it is useful to some people ;)

GitHub: unity-php-secure-communication

<?php
<?php
/**
 * test with curl:
 *
 *  // Generate keypair : return XML public key
 *  curl -c cookies.txt -d "keygen=1" http://exemple.com//encrypt.php
 *
 *  // Test encrypt/decrypt : return encrypted and decrypted `my text to encode`
 *  curl -b cookies.txt -d "test=my text to encode" http://exemple.com//encrypt.php
 *
 *  // Test encrypt : return encrypted
 *  curl -b cookie.txt -d "encrypt=my text to encode" http://exemple.com//encrypt.php > encrypted.txt; cat encrypted.txt
 *
 *  // Test decrypt : return decrypted `my text to encode`
 *  curl -b cookie.txt -d "decrypt=`cat encrypted.txt`" http://exemple.com//encrypt.php
 */

include 'vendor/autoload.php';
use phpseclib\Crypt\RSA;

function generateKeyPair(){
    if (!isset($_SESSION['publickey'])){
        $rsa = new RSA();
        $rsa->setPrivateKeyFormat(RSA::PRIVATE_FORMAT_XML);
        $rsa->setPublicKeyFormat(RSA::PUBLIC_FORMAT_XML);
        $keys = $rsa->createKey();
        $_SESSION['privatekey'] = $keys['privatekey'];
        $_SESSION['publickey'] = $keys['publickey'];
    }
    return $_SESSION['publickey'];
}

function encrypt($cleartext){
    $rsa = new RSA();
    $rsa->setEncryptionMode(RSA::ENCRYPTION_PKCS1);
    $rsa->setPublicKeyFormat(RSA::PUBLIC_FORMAT_XML);
    $rsa->loadKey($_SESSION['publickey']);
    $bytesCipherText = $rsa->encrypt($cleartext);
    return rawurlencode(base64_encode($bytesCipherText));
}

function decrypt($encrypted){
    $rsa = new RSA();
    $rsa->setEncryptionMode(RSA::ENCRYPTION_PKCS1);
    $rsa->setPrivateKeyFormat(RSA::PRIVATE_FORMAT_XML);
    $rsa->loadKey($_SESSION['privatekey']);
    $bytesCipherText = base64_decode(rawurldecode($encrypted));
    return $rsa->decrypt($bytesCipherText);
}

if (isset($_POST['session_id'])) {
    session_id($_POST['session_id']);
}
session_start();

if (isset($_POST['keygen'])) {
    echo generateKeyPair();
    exit();
}

if (isset($_POST['encrypt'])) {
    echo encrypt($_POST['encrypt']);
    exit();
}

if (isset($_POST['decrypt'])) {
    echo decrypt($_POST['decrypt']);
    exit();
}

if (isset($_POST['test'])) {
    generateKeyPair();
    $ciphertext = encrypt($_POST['test']);
    echo "encrypted: $ciphertext\n\n";
    $clearText = decrypt($ciphertext);
    echo "decrypted: $clearText\n";
    exit();
}
using System;
using System.Collections;
using System.Security.Cryptography;
using System.Text;
using UnityEngine;
using UnityEngine.Analytics;
using UnityEngine.Networking;
using UnityEngine.UI;


public class EncryptController : MonoBehaviour
{
    public string ScriptUrl = "http://example.com/encrypt.php";

    public InputField ClearTextInputField;
    public InputField EncryptedTextInputField;
    public InputField ClearResponseInputField;

    public Text SessionIdText;
    public Text PublicKeyText;

    public void OnKeygenButtonClick()
    {
        StartCoroutine(GenerateRsaKeyPair());
    }

    public void OnEncryptButtonClick()
    {
        if (PublicKeyText.text.Length < 100)
        {
            Debug.LogError("You must generate RSA key pair before");
            return;
        }
        var csp = new RSACryptoServiceProvider(1024);
        csp.FromXmlString(PublicKeyText.text);
        var plainTextData = ClearTextInputField.text;
        var bytesPlainTextData = Encoding.Unicode.GetBytes(plainTextData);
        var bytesCypherText = csp.Encrypt(bytesPlainTextData, false);
        var cypherText = Convert.ToBase64String(bytesCypherText);
        EncryptedTextInputField.text = cypherText;
    }

    public void OnDecryptButtonClick()
    {
        if (PublicKeyText.text.Length < 100)
        {
            Debug.LogError("You must generate RSA key pair before");
            return;
        }
        StartCoroutine(SendEncryptedText(EncryptedTextInputField.text));
    }

    IEnumerator GenerateRsaKeyPair()
    {
        var form = new WWWForm();
        form.AddField("keygen", 1);
        form.AddField("session_id", AnalyticsSessionInfo.sessionId.ToString());
        SessionIdText.text = "sessionId=" + AnalyticsSessionInfo.sessionId.ToString();

        using (var www = UnityWebRequest.Post(ScriptUrl, form))
        {
            yield return www.SendWebRequest();

            if (www.isNetworkError)
            {
                Debug.LogError(www.error);
            }
            else
            {
                LogHeaders(www);

                Debug.Log(www.downloadHandler.text);
                PublicKeyText.text = www.downloadHandler.text;
            }
        }
    }

    IEnumerator SendEncryptedText(string text)
    {
        var form = new WWWForm();
        form.AddField("decrypt", text);
        form.AddField("session_id", AnalyticsSessionInfo.sessionId.ToString());
        SessionIdText.text = "sessionId=" + AnalyticsSessionInfo.sessionId.ToString();

        using (var www = UnityWebRequest.Post(ScriptUrl, form))
        {
            //www.SetRequestHeader("cookie", SessionIdText.text);
            yield return www.SendWebRequest();

            if (www.isNetworkError)
            {
                Debug.LogError(www.error);
            }
            else
            {
                LogHeaders(www);

                // Print Body
                Debug.Log(www.downloadHandler.text);
                ClearResponseInputField.text = www.downloadHandler.text;
            }
        }
    }

    private void LogHeaders(UnityWebRequest www)
    {
        var sb = new StringBuilder();
        foreach (var dict in www.GetResponseHeaders())
        {
            sb.Append(dict.Key).Append(": \t[").Append(dict.Value).Append("]\n");

            if (dict.Key == "Set-Cookie")
            {
                SessionIdText.text = dict.Value + " (from response headers)";
            }
        }
        Debug.Log(sb.ToString());
    }
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!