“Secure
HTTP” without HTTPS
in Unity
Quick Guide v1.21
by SEMO Graphics, Inc.
(2019.03.07)
support: master@semographics.com
------------------------------------------------------------
Unity and Unity
Pro is the game engine created by
Unity Technologies.
Introduction
You can
set your own “Secure HTTP” system up without HTTPS in any of the cross
platforms (iOS, Android, Webplayer, and Standalone) in Unity.
In this quick guide, with “Secure HTTP” I will explain, step by step, what
needs to be done on your project in order to get a secure HTTP service without
HTTPS in a day.
But “Secure
HTTP” is not only a guide or a tutorial, it comes with all the server-side script
(php) and client-side code (C#), together with an example Unity Scene and
scripts to show its capabilities.
In
this quick guide, The details regarding encryption algorithm was not explained.
I focused on HOW to USE “Secure HTTP”.
In “Secure HTTP” system, there are no hidden binary codes, we provide full
client and server source codes. If existing source codes are not satisfactory,
you can change it.
Supported
client platforms: Android, iOS, Webplayer, Standalone
Supported server script: PHP5 or PHP7
Supported
DB for key storage: File, MySQL, and PostgreSQL.
Prerequisite
Client : Unity >
5.x (work on Unity 2017 & 2018)
Server:
PHP > 5.x or 7.x, OpenSSL or mcrypt,
iconv and hash (optional) module. “Secure HTTP” support only php sever script.
If your server script is ASP, JSP you can NOT use “Secure HTTP”.
What is “Secure
HTTP without HTTPS”?
In
Unity, whenever you connect to web server, “Secure HTTP” encrypts your plain
text parameters with AES256 bit algorithm and sends encrypted texts to web server.
And In client, It also decrypts all encrypted response text from your server.
For Example(GET request)
Your plain URL text.
http://www.yourdomain.com/smaes/test_get.php?returnval=Secure_HTTP_without_HTTPS! |
Encrypted URL text with “Secure HTTP
without HTTPS”
(you may use SMUtil.encryptURL(str)
in client.)
http://www.yourdomain.com/smaes/test_get.php?deviceid=4b46360202cfc0bb2c9924c5f0441cf4c2593131&returnval=LNzFB2E5cDj26AnYpbAHywucM0U/dfte+oytIMCfuGE=$&returnval_PC=3A4pJwrOgL4Aw2welnT7NE51HO4TqSsVxPyPWIXQ4oM=$ |
Server accepts the request and sends the result encrypted text.
LNzFB2E5cDj26AnYpbAHywucM0U/dfte+oytIMCfuGE=$ |
Decrypted result text in Client
(You may use SMAES.decryptIf(str) in
client)
Secure_HTTP_without_HTTPS! |
* We also support POST request too.(not support binary file upload)
Run
& test prebuilt web/android app
WebPlayer
Demo: just visit the URL.
http://www.semographics.com/smaes_webplayer/smaes_webplayer.php
Android
Demo: download apk and run it on your android device (>4.1)
http://www.semographics.com/smaes_webplayer/secure_http.apk
“Secure
HTTP” support IOS device.
“Secure
HTTP” support Standalone(Windows and etc).
http://www.semographics.com/smaes_webplayer/smaes_win32.zip
What
do we start?
“Secure HTTP” is cross-platform system; it can be used
in iOS, android, webplayer, standalone at the same time. If that is not your
case, I suggest you skip the section that does not suit you, as it won’t affect
the rest of the quick guide. Of course, if you need cross-platform you will
need to read it all! But hey, it’ll be worth it.
Server
check: PHP with mcrypt, iconv, hash
As mentioned in the Asset Store, you need to have a
remote server that is able to run PHP files. This server will accept the
client’s secure request and send the secure result to the clients back.
1)
Import the “Secure HTTP” package in your project
There are core files such as smaes.cs or etc, In “Secure_HTTP_core”
folder.
Sample scenes and scripts are in “Secure_HTTP_examle”
folder.
Since
ver1.21, There are no javascript files. There are only C# files in package. We
don’t need to move “Secure_HTTP_Core” folder to Plugins folder. Because we don’t
use javascript scripts any more.
Check the following link regarding it.
https://blogs.unity3d.com/2017/08/11/unityscripts-long-ride-off-into-the-sunset/
Import the “Secure HTTP” in you project then you could find
server_php_script.zip file in Secure_HTTP_example folder.
2) Upload all PHP
files to your server
The files provided in this package under the
Secure_HTTP_example /server_php_script.zip needs to be uploaded to your server.
Unzip “server_php_script.zip” and
upload smaes folder to your remote server. (Maybe /smaes ). You don’t need server_php_script.zip in client side
any more.
in smaes folder, you can see 15 php files.
In your PC or Mac, run your browser and visit the
following URL .
http://yourdomain.com/smaes/test_test.php
If you see the previous result then your server is
ready to run “Secure HTTP”. If you have any problems in test_test.php page, run
phpinfo(); and find the OpenSSL, mcrypt, iconv, hash modules ( CTRL+’F’ and type
‘mcrypt’ )
<?php
phpinfo();
?>
In your phpinfo() page, you should check if mcrypt,
hash and iconv are installed or not.
OpenSSL(default)
or mcrypt
is required to run “Secure HTTP”. OpenSSL
is default encryption/decryption API. But iconv and hash are
optional components. If you really want to use “Secure HTTP” without iconv and hash php module. You may change the server script as follows (NOT
RECOMMENDED)
Edit the /smaes/SMAES.php file in your remote server (yourdomain.com).
If you don’t have iconv module in
php
If you don’t have hash (md5) module in php
Your server (yourdomain.com) is ready to accept secure
request from the clients now.
Change
client and server configuration – steps
What
you need:
-
Unity License
-
Putty or telnet to login your remote
server(yourdomain.com)
-
Android device
-
Web browser (firefox or chrome or else)
1) Set your server name in client-side
Open “plugins/Secure_HTTP_core/SMServer.cs”
change m_ServerPath to “http://yourdomain.com/smaes/”
2) Change the m_prm_ky in both client and
server
-
Client-side
Open the “plugins/Secure_HTTP_core/SMAES.cs”
Change m_prm_ky in SMAES.cs with your own
string.
m_prm_ky:
- more than 32bytes
(for instance: “think_your_own_string_which_is_hard_to_guess”
)
- m_prm_ky is
something like personal room key. Don't reveal the m_prm_ky to anyone including
your girl or boy friend(s).
l
You MUST and SHOULD change m_prm_ky value and don't forget to
change in both client and server!
-
Server-side
Modify
$m_prm_ky value in your server ( /smaes/SMConfig.php )
Run
client on android - step
1) Switch plaform to Android and check
Development build to show full log message.
2) Set Build Setting/Player setting
3)
Run example
main scene( smmain.unity )
4) Change GET parameter and check them
5)
Change
POST parameter and check them
You
successfully installed “Secure HTTP” and check it’s function. From now on, you can migrate your source codes from “Plain
HTTP” to “Secure HTTP”.
(You don’t need Secure_HTTP_example folder any more.)
How
to integrate with BestHTTP
*.BestHTTP is external useful
HTTP asset in Unity Asset store. (You can use “Secure HTTP” without BestHTTP).
BestHTTP store link:
https://assetstore.unity.com/packages/tools/network/best-http-10872
If you want to use Secure HTTP with BestHTTP, Check the following steps
1) To Enable BestHTTP exaxmle, define the “USE_BESTHTTP”
in setting.
In
“Project/Other Settings/Scripting Define Symbols*” menu, add symbol “USE_BESTHTTP”.
2) run “BestHTTPexample”
3) check the scene “BestHTTP POST,GET URL”
4)
Regarding
BestHTTP example, check the following scripts
example_besthttp_cs
, example_besthttp_cs.cs
Client-side
source migration - step
1) Find all “WWW” in your project
2) Manage GET request and result text
Before
request, encrypt URL : url = SMUtil.encrptURL(URL);
Before
processing result text: result = aes.DecryptIf(www.text);
3) Find all “WWWForm” in your project
Replace
WWWForm with SMWWWForm.
4) Manage POST parameters and result text
WWWForm
is the member variable of SMWWWForm. SMWWWForm is the just wrapper class to
encapsulate encryption function.
Before request,
Before processing result text: result = aes.DecryptIf(www.text);
5) Read the SMwww.cs in “Plugins/Secure_HTTP_core”
folder
Server-side
source migration - step
1) Edit php source
- In
server-side, you can simply add SMAES header and footer part in your script. You
may need to make 1 result string to encrypt in your original source part.
-
Edit SMConfig.php in server-side (debug or production ?)
$SMCONFIG['debug']
= true; // when debug
$SMCONFIG['debug'] = false; // when
production
Important
things to rememeber!
-
m_prm_ky should be more than 32bytes.
And change it in both client and server at the same time.
-
Don’t use the following parameter names when GET, POST requests.
deviceid:
intrinsic variable name when requesting GET, POST.
*_PC : If
you add variable “varname” to GET or POST, then “varname_PC” variable will be
automatically added to validate it’s values.
// refer SMUtil.encryptURL(),
SMWWWFORM
varname_PC = md5(varname);
- You
can see server’s log from following URL.
http://yourdomain.com/smaes/test_console.php
- If you think that “Secure HTTP” does not work, you can debug it, check http://yourdomain.cm/smaes/test_test.php. You may
find debug log file path like “/var/tmp/smaes-error.log”
tail –f /var/tmo/smaes-error.log
- I strongly
recommend that you send and receive all GET or POST parameters in one JSON
string. You can parse simply JSON in php and C#. It will be more secure than transferring
every variables between the server and clients.
- Maximum
length of HTTP GET request?
http://stackoverflow.com/questions/2659952/maximum-length-of-http-get-request
- Cross
domain error in webplayer:
http://docs.Unity.com/Manual/SecuritySandbox.html
- AES(Advanced
Encryption Standard) : The Advanced
Encryption Standard (AES) is a specification for the encryption of electronic
data established by the U.S. National Institute of Standards and Technology
(NIST) in 2001.
http://en.wikipedia.org/wiki/Advanced_Encryption_Standard
To be
more secure, you can update client’s prm_ky generated on Server. Whenever
client connects like session.( v1.11)
m_prm_ky is the private key. We can change and synchronize it between client
and server. Everytime client connects.
To update m_prm_ky, you can use SMKey.cs
in client and syncKey.php in server.
In unity editor, load “example_replace_prm_ky”
scene and run it.
Cient’s
prm_key is updated and Server’s prm_key is also updated when request synKey.php
in server.
And
you can see the prm_ky is changed in window.
( set $SMCONFIG[“storage”] to “file”
in SMConfig.php )
-
How to
syncKey in Client
-
How to
syncKey in Server. ( edit SMConfig.php)
You
can set $SMCONFIG[“storage”].
none: NOT
use key storage, just use initial prm_ky.(no change prm_ky)
(valid
any number of web servers) - default
file :
generate prm_ky whenever "syncKey.php" is called. and save it to file
storage.(valid only 1 web server)
mysql : generate prm_ky whenever
"syncKey.php" is called. and save it to MySQL.(valid any number of
web servers)
psql : generate prm_ky whenever
"syncKey.php" is called. and save it to PostgreSQL(valid any number
of web servers)
-
You can call syncKey() at anytime, after
syncKey() your prm_ky is changed to value. (you may wait until synKey() is
finished)
-
syncKey() encrypt url and decrypt result
with deviceid as prm_ky.
-
If you choose “none” as storage, we did
not change key and always use initial prm_ky as encryption and decryption.
-
“file” storage is selected when you have
only 1 web server. Because prm_ky is saved in server disk.
-
If you have more than 2 web servers, you
should choose DB storage(“mysql” or “psql”) to synchronize keys between client
and server.
// MySQL table
CREATE
TABLE `EveryDB`.`SMKey_tbl` (
`key_id`
VARCHAR( 255 ) NOT NULL ,
`key_val`
VARCHAR( 255 ) NOT NULL ,
`key_ip`
VARCHAR( 255 ) NOT NULL ,
`key_date`
VARCHAR( 255 ) NOT NULL ,
`etc`
VARCHAR( 255 ) NOT NULL ,
UNIQUE
( `key_id` )
)
COMMENT = 'SMKey table';
// PostgreSQL
table
CREATE
TABLE SMKey_tbl (
key_id
varchar(255),
key_val
varchar(255),
key_ip
varchar(255),
key_date
varchar(255),
etc
varchar(255),
CONSTRAINT key_id_idx
UNIQUE(key_id)
);
Create
table in you DB(MySQL or PostgreSQL) and edit SMConfig.php with proper values.
-
$SMCONFIG[“SSL_TYPE”]
OPENSSL:
select openssl as encryption and decryption API (default since v1.20)
MCRYPT: select
mcrypt as encryption and decryption API (NOT recommended)
https://paragonie.com/blog/2015/05/if-you-re-typing-word-mcrypt-into-your-code-you-re-doing-it-wrong
if you change $SMCONFIG[“SSL_TYPE”], then
you should change in client at the same time.
in client (SMAES.cs)
// // m_CryptType: Set Crypt type (OpenSSL or MCrypt) // (important!) you should change this value in both
client(SMAES.cs) and server(SMAES.php) at the same time. // enum SSL_TYPE { OPENSSL, MCRYPT }; // OPENSSL or
MCRYPT static private SSL_TYPE m_CryptType =
SSL_TYPE.OPENSSL; |
-
$SMCONFIG[“OPENSSL_METHOD”]
이 값에 따른 동작
aes-256-cbc: openssl method (Don’t change!)
Version
Control
Version 1.21 (2019.03.11)
-
Delete all Javascript example scene and
scripts.
-
Update documents regarding JS.
Version 1.20 (2019.03.07)
-
Support alternative encryption
API(OpenSSL) and OpenSSL is default.
-
Add BestHTTP example, scene and scripts
(example_besthttp_cs , example_besthttp_cs.cs)
-
Fix the a couple of bugs(SMUtil.cs) and
errata
Version 1.13 (2015.03.08)
-
Support server log viewer in client( yourdomain.com/smaes/test_console.php
)
-
Fix test_test.php page.
-
Fix the bug regarding UTF8 issue. (Thanks
to Park Ju Sung, he helped me to fix it)
Version 1.11 (2015.02.09)
-
We can update and synchronize prm_ky
between client and server. whenever client connects. (Thanks to Robin Tan, he
provided private key sync idea.)
Version 1.02~1.05
-
Fix some errata
-
Version 1.01
-
Created