So, you want to communicate data between your app and web server?

Before we delve into this, you may want to read about the legal implications on including encryption in your app, how to configure an HTTPS server and how to encrypt data in your app.

Once we are done here, you’ll have a good foundation for being able to send encrypted data between our app and web server. This just adds an extra layer of protection on top of HTTPS along with giving you the chance to store encrypted data on the local device. So, what’s the first thing we need to do? Let’s take a look at the functionality Unity provides to communicate with a web server. There are two classes we’ll look at for this, “WWW” and “WWWForm”. Unity makes it pretty easy to send info to a web server and wait for the result. Here is a basic example of how to do this:


// Set up form to send POST data
WWWForm wwwForm = new WWWForm();
wwwForm.AddField("yourField", data);

// Send data and wait for result
www = new WWW("https://yourUrlHere", wwwForm);
yield return www;
error = www.error;

// Process the data
if (String.IsNullOrEmpty(error) == true) {
  ProcessResults(www.text);

You can add as many fields as you would like for sending data to your web server. So if you were sending a player name and a score, you create two fields on your WWWForm object. When you send the data, your script on the web server will process the data and send back a result that your app can then respond to. One thing to point out, we use a “yield return www” statement, this effectively allows the app to continue without waiting for a response from our web server. That yield statement is where the app is just waiting for the script shown below to complete while allowing the other code to run. This is done through coroutines which I’ll talk about in a bit. For now lets jump to the PHP side to see how we’d process this info and then we’ll get into a more complicated example that includes retrying our result if there was a problem and encrypting the data before we send it to our web server.

So in PHP on your web server we’ll access the data in the request using the $_POST variable. This will look something like this:

// Note that we named the variable "yourField" from
// the C# portion of the code above
$yourFieldData = $_POST["yourField"]; 

// Do something here with $yourFieldData like insert it in a database

header("Access-Control-Allow-Origin: *");
print("Some sort of return value(s) for your app to process");

That is what we are looking at from the PHP side. We take the data sent in from our app, process it, then respond by outputting something that our app will then read  Maybe like a return code so it knows if things were process properly or the ranking of the record just inserted in comparison to all the other records in that table. Now that we’ve got the basic idea down of how that all works, we can add things to it like encryption and retrying if there was a communications issue. I’ll cover caching the results to the device in another post so that if the user quits out of the game and the data hasn’t been saved yet to our server or there was a complete loss in communications, the request will be retried again later. For now, we are going to assume the transaction goes through the 2nd or 3rd time we try it if there was a slight hiccup in the communications between our app and the web server.

First thing we’ll do is setup our code for making calls to our web server. I created a script named DAO.cs (This stands for Data Access Object) and made it a static singleton instance. The reason I did this was because StartCoroutine is a method of the Monobehaviour class and needs an instance to be able to be called since StartCoroutine is not static. If StartCoroutine is called from a script that can be destroyed (i.e. calling your StartCoroutine then calling Application.LoadLevel() right afterwards), the StartCoroutine also dies because it is called from your scene’s instance (derived from Monobehaviour) even if that call to StartCoroutine isn’t finished yet. This had me very confused at first when my coroutine was killing out during an HTTPS request because I had called a LoadLevel() to get to the next scene of my app. I assume (falsely) that a coroutine was similar to a thread and would continue independent of what had called it. So came the necessity to make our DAO script and attach it to a game object that just goes with us through the life of that gaming session. In the script below, you see the methods themselves of the DAO class are static, but we still use the static singleton instance of the DAO object to call StartCoroutine from. I guess you don’t have to make the DAO methods static since you have a static singleton instance of the DAO class following you around, but when I first designed it, I didn’t think I’d need this static singleton DAO instance. The following code is more of a guide/example, I pulled it from one of my working projects and cut it down a bit, so you’ll have to modify it to fit your needs.

For passing data in your POST, you could pass a separate key/value for each and just encrypt the values on each key. What I decided to do is have just one key and pass in multiple key/values on that one parameter and separated each key/value with a pipe. I let my PHP code split up everything once the payload made it there. You could also use serialization or pass the data in an XML string if you wanted. So, in effect, what I have is a query string passed to the web server that looks something like “https://some-web-page.php?data=key1=value1|key2=value2|key3=value3“. However you decide to pass data to your web server is really up to you.

Some things to note:

  • Wait…you can’t pass an equal sign/spaces/whatever special character safely to your web server without URL encoding it! Yes, you are right, but my payload is encrypted (via the Crypt class) and effectively URL encoded. So passing equal signs are okay here since the value part of the “data” parameter looks something like “g1tThXzmX1Mjunux1Eto5YA” when it is sent along its way to the web server.
  • Make sure the function you want to call via StartCoroutine has a return parameter of IEnumerator. This will allow us to do some nice things like yield for a return while allowing the rest of the code to run. Pseudo-multi-threading I guess is the best way to define this.
  • We define a maximum amount of attempts we’ll try the request ALONG with a slight pause in between trying multiple times. If there is a small hiccup in communications, we want to give the device a little bit of time to correct before retrying.
  • www.text will be the response we receive from the web server. Again, this is up to you on how you want your PHP script to respond to this request. For your PHP script to respond, all you have to do is simply print() something before exiting the PHP script.
  • You did read How can I securely save my app data?, right?
  • Don’t hate on the use of prepended underscores for private variables 🙂
using UnityEngine;
using System;
using System.Collections;

public class DAO : MonoBehaviour {

  // Specific instance of this class
  public static DAO instance = null;

  // Max attempts to send data to the web server
  private static int _maxAttempts = 3;

  /**
  */
  void Start() {
    // Making sure we only have one instance of this game object
    if (DAO.instance == null) {
      DAO.instance = this;
      DontDestroyOnLoad(this);
    }
    else {
      Destroy(gameObject);
    }
  }

/**
 */
  public static IEnumerator GetScores() {
    int attempts = 0;
    string error = "ERROR";
    WWW www = null;
    // This is the payload to your web server. For a simple
    // GetScore type of functionality, you might pass it
    // a date to get scores inserted past a specific date
    string data = "key1=value1|key2=value2";
    // This is the key you share between your app and
    // your web server so that you can encode/decode
    // information
    string key = "yourKeyHere";
    string encryptedData = Crypt.Encrypt(data, key);

    // Try maxAttempts times to get the data
    while (attempts < DAO._maxAttempts && String.IsNullOrEmpty(error) == false) {
      // Sleep for 3 seconds before trying multiple times
      if (attempts > 1)
        yield return new WaitForSeconds(3f);

      // Set up form to send POST data
      WWWForm wwwForm = new WWWForm();
      wwwForm.AddField("data", encryptedData);

      // Send data and wait for result
      www = new WWW("https://yourURL", wwwForm);
      yield return www;
      error = www.error;
      attempts++;

      // Process the data and put it into an
      // array if there were no errors
      if (String.IsNullOrEmpty(error) == true) {
        DAO.PopulateScores(www.text);
      }
      else {
        // Handle any errors here
      }
    }
  }

/**
 */
  public static void PopulateScores(string text) {
    // This is the key you share between your app and
    // your web server so that you can encode/decode
    // information
    string key = "yourKeyHere";
    try {
      string decryptedText = Crypt.Decrypt(text, key);
      if (decryptedText.Contains("|") == true) {
        string[] scores = decryptedText.Split('|');
        // Do something with "scores"
      }
      else {
        // Invalid return from web server
      }
    }
    catch (Exception e) {
      // Handle exception here
    }
  }
}

To call this from your app, all you have to do is something like:

DAO.instance.StartCoroutine(DAO.GetScores());

This uses the instantiated static singleton DAO object “instance” to call StartCoroutine on the static method GetScores(). And because we are using a static instance, we don’t have to worry about the coroutine killing out if we go to another scene while the coroutine might still be running.

So how about the PHP side of things? In this example, we are retrieving scores from a database and returning the data so the app can do something with that data like display it. Again, how you decide to structure the return data is up to you. We could easily return something like “score1|score2|score3|score4” (which is the structure this example is expecting) and when our app receives the data, splits the string into an array or you could use serialization on your objects or even XML as well. It would probably be more “proper” to use serialization or XML. I’m actually not very fond of using XML in this instance due to how verbose XML can be. I want the smallest amount of data transfer as possible…especially with mobile devices.

For pulling back the scores, let’s pretend we have a table named “PlayerScores” in our MySQL database and it consists of three columns, an “id”, “name” and “score”. Below is some PHP code that uses this structure to query for the data and send it to our app who is patiently waiting for a response from our web server via the “yield return www” C# statement.

Some more things to note:

  • Procedural code? That’s so 1990s. Yeah well, think of it as an exercise to convert it to object oriented code.
  • Wait…where did “Decrypt” come from? That isn’t a PHP function. Yup, you are right. “Decrypt” is one of the the sister functions to our Crypt class in C#. More on that a little later.
  • Again, this code is cut down from one of my projects and so doesn’t have some error handling, so it may not be fully functional as is but it gives you a very good direction on how to go about doing something like this.
  • Depending on how you passed the data in your POST from your app, you will need to design your “WhateverFunctionYouCreateToExtractYourData” function to handle it.
  • Whats up with the header(“Access-Control-Allow-Origin: *”); code in your PHP? This just has to do with my Unity Web Player hosted on Dropbox trying to call my PHP scripts on a different domain. I’m just letting the browser know it is okay to do this.

<?php
  // Include whatever classes and files you need here

  // Make sure things look right from the request
  // This simply makes sure we are communicating across HTTPS
  // and "data" is present in our POST
  if (!isset($_SERVER["HTTPS"]) || !isset($_POST["data"])) {
    die();
  }

  $key = "whateverKeyYouUsedInTheAppToEncryptTheData";
  $decryptedData = Decrypt($_POST["data"], $key);
  $values =
    WhateverFunctionYouCreateToExtractYourData($decryptedData);

  // Check to make sure all expected keys are present
  if (!isset($values["key1"]) || !isset($values["key2"])) {
    die();
  }

  // You'll have to supply the connection information below
  // based on how your database is setup
  $link = mysqli_connect($server, $userName, $password, $database);
  $result =
    mysqli_query($link, "SELECT score FROM PlayerScores ORDER BY score DESC");

  // Putting scores into data
  $allScores = array();
  while (($scores = mysqli_fetch_assoc($result)) != false) {
    $allScores[] = $scores;
  }

  // Cleaning some things up
  mysqli_free_result($result);
  mysqli_close($link);

  // Encrypting the data and sending it back to the requestor
  $encryptedData = Encrypt(implode("|", $allScores), $key);
  header("Access-Control-Allow-Origin: *");
  print($encryptedData);
?>

For this to all work like it needs to, our PHP code needs to be able to decrypt the data sent to it and then encrypt a response. Before returning our scores, we encrypt the string and print() it out. Once the script does this, the “yield return www” completes and we now have our response data in www.text on the C# side. Here is how you’d create some Encrypt/Decrypt functionality on the PHP side. Most of this encryption/decryption code here is NOT mine.

<?php
  /**
   *
   * @param Info to encrypt $data
   * @param Used to generate key $secret
   */
  function Encrypt($data, $secret) {
    // Generate a key from a hash, use 192 bit key
    $key = bin2hex(substr(md5(utf8_encode($secret), true), 0, 12));

    // Pad for PKCS7
    $blockSize = mcrypt_get_block_size('tripledes', 'ecb');
    $len = strlen($data);
    $pad = $blockSize - ($len % $blockSize);
    $data .= str_repeat(chr($pad), $pad);

    // Encrypt data
    $encData = mcrypt_encrypt('tripledes', $key, $data, 'ecb');
    return (base64_encode($encData));
}

  /**
   *
   * @param Info to decrypt $data
   * @param Used to generate key $secret
   */
  function Decrypt($data, $secret) {
    // Generate a key from a hash, use 192 bit key
    $key = bin2hex(substr(md5(utf8_encode($secret), true), 0, 12));
    $data = base64_decode($data);

     // Decrypt data
    $data = mcrypt_decrypt('tripledes', $key, $data, 'ecb');
    $block = mcrypt_get_block_size('tripledes', 'ecb');
    $len = strlen($data);
    $pad = ord($data[$len-1]);
    return (substr($data, 0, strlen($data) - $pad));
  }
?>

The PHP code feels a bit simpler than the C# code for encrypting/decrypting. Once you have this in a PHP script, include it in the other script above, then you can call Encrypt() and Decrypt() to your heart’s desire! Now your app and web server should be able to send encrypted data to each other across HTTPS! Got any suggestions or tips? Share them in the comments below, I’m always looking for ways to make my code better.

Some final thoughts about “Jumble Attack”

“Jumble Attack” is now live on the Google Play Store, Amazon App Store, Apple Appstore and Facebook! From cradle to grave this little app took us about a month and a half to complete which isn’t too bad considering some of the new technologies we introduced into our game along with the authorizations we had to get from the government. I was a little concerned about the restrictions Apple places on their apps as it is sometimes difficult to get approval, but the approval went through the first time…it still took a good 7 days though from submissions until they approved it. Now that we’ve figured out how to encrypt data, include in-app purchases and communicate with a web server, we can concentrate on the content in our next game rather than how to make the technology work. We are pretty excited about our next project, but it is a lot larger than anything we’ve done thus far. If you like card games with a twist, stay tuned for more info about our next project, Kung Pow Cards!

Poor man’s HTTPS

If you are thinking of using HTTPS to communicate data or encrypting your data in your apps, please read this post first

What do you mean I have to be “properly authorized” to use encryption in my apps?

We were looking at adding some interaction between our mobile apps and our web server and wanted to use HTTPS for this so we’d have a layer of security on top of the communications. I had never setup HTTPS on a web server before, but knew a decent amount of what would have to go into it. So I started looking around cPanel and found the following icon under “Security”

SSL/TSL

After clicking this icon, we are taken to an area where we need to do three things. First is to generate a private key, the second is to create a Certificate Signing Request (CSR) and lastly, place a certificate on our server. Luckily the interface in this version of cPanel (v11.44.1 (build 18)) makes it pretty easy to do.

 

Screen Shot 2014-09-09 at 8.38.48 PM

Screen Shot 2014-09-09 at 8.38.18 PMAfter clicking on the “SSL/TSL” icon, Click on the link here to go to the next screen to generate a private key.  I just used our company name in the description. Once the private key is generated, make sure to save it to a file on your computer.

 

 

 

 

 

Screen Shot 2014-09-09 at 8.38.55 PMScreen Shot 2014-09-09 at 8.39.24 PM

For a Certificate Signing Request
(CSR), go back to the previous screen and click on the link to generate a CSR, select the description you chose in the previous step in the drop down box and fill out the rest of the information and generate your CSR. Again, save it to a text file.

 

Screen Shot 2014-09-09 at 8.39.01 PMScreen Shot 2014-09-09 at 8.40.05 PM

Once this is done, go back to the previous screen again and manage the certificates on your web server. Install a self signed certificate by filling out the information and selecting the key you want to use. Now, a self signed certificate will allow you to use HTTPS on your site BUT you’ll be greeted with an ugly warning message by the browser that the site could not be verified so the certificate could not be trusted. We’d need to send off the CSR we created in the previous step to a Certificate Authority (CA) to receive a verified certificate to remove that warning from the browser.

Well, we only need HTTPS for communications between our app and our web server; so a self signed certificate should be good enough since the user won’t be interacting directly with our website across HTTPS. I did a quick search to see how much a certificate would cost, they vary wildly but seeing stuff for $175/yr. Why spend money on something we don’t need immediately? But, we do have everything we need to get a valid certificate if we decide to use HTTPS for direct user interactions with our website. That is why I call this the poor man’s HTTPS.

Updated:

So I’ve now come across a site that offers free SSL certificates. WOO HOO! I’ve seen mixed reviews, some people swear by them, others don’t seem to like them very much. But I thought I’d give it a shot. The site is https://www.startssl.com. Since I already created my certificate with them, I can only go through the steps again so much.  But it should be enough to figure out. What got me looking at this again was since we are communicating data between our website and our app, the Unity Web Player relies on the browser and JavaScript to do that (More on that one in a later post). Since our web server was only using a self signed certificate for HTTPS, the browser was blocking/complaining about the JavaScript AJAX calls to our web server when running the app using the Unity Web Player. This makes sense, but it didn’t occur to me during development.

Login Page

Head on over to https://www.startssl.com/?app=12. Just click the “Sign-up” button to get started. Please note the first time I tried this, their site was having some overloading issues…I just patiently waited a bit and was able to get on after a while.

Sign Up

There really isn’t too much information here to fill out, but please READ CAREFULLY and take your time to make sure you’ve filled the information out properly. The reason I say this is because there appears to be a price on revoking an SSL cert. Once you’ve finish the sign up process, they’ll send you an email to confirm your account.

homeOnce you have verified your account, StartSSL asks to install a certificate in your browser so you can log in. So if you go to https://www.startssl.com, you should see a page similar to the following. If not, just click the “Authenticate” button.

 

manage-certsIt would be a good idea to back up this certificate they just gave you. In Chrome, you can do it this way: Go to “Settings”, then click the “Advanced” link at the bottom. Find HTTP/SSL “Manage Certificates” and click on it. Find the one for StartSSL and export it and keep it somewhere. This will allow you to reimport the certificate at a later time if you need to.

Validate Domain Name - Step 1

Now we need to let them know that we own the domain we are attempting to get a class 1 SSL cert for.  I don’t know exactly the differences between all the classes of SSL certs, but we only need a class 1 for our purpose. I do know that a Class 1 doesn’t support wildcard domains but it will support a top domain name and a sub-domain…in fact it asks you to specify a sub-domain later in the process. So, once you’ve navigated back to https://www.startssl.com, click on the “Validation Wizard” tab and select “Domain Name Validation” from the drop down box.

Validate Domain Name - Step 2

Just put in your domain name here, pretty easy really.

 

 

Validate Domain Name - Step 3

 

It takes a couple of seconds, but a list of email addresses associated with the domain name pop up. You have to have control over one of those email addresses so they can send you a link for domain verification. Just pick one from the list that you are in control of and click “Continue”. Again, I had some issues with this part of the process. It kept telling me it could not verify the email address.  So again, I waited and after a bit it worked. Once you get the email, follow the directions to verify that you own the domain.

Create SSL Cert - Step 1

Now we are able to create an SSL cert for our domain! Click on the “Certificates Wizard” tab at the top and select “Web Server SSL/TLS Certificate” from the drop down box.

 

Create SSL Cert - Step 2

 

From here we can create the keys we need to create our certificate…but we already did that earlier, so click the “Skip” button.Create SSL Cert - Step 3

 

 

Go and find the Certificate Signing Request (CSR) that you saved earlier…you DID save it, right? Simply open it up in a text editor, copy the contents and pate them into the provided box.  Make sure you get the header and footer! Continue following the directions to finish up. After a while (I think I waited about an hour), you’ll receive an email that says you now have a certificate.

 

Retrieve CertClick on the “Tool Box” tab there at the top and select “Retrieve Certificate” from the list of options on the left. After selecting the certificate, (it should already be selected) click the “Continue” button to reveal the certificate.  Copy and paste this info into a plain text file. Once you have this, go back to your web server and install the certificate just like you did for your self signed certificate. Then just remove your self signed certificate.  One of the things I noticed was that even though https://www.nikywilliams.com was covered under the SSL cert, https://www.nikywilliams.com was not. At the moment, this isn’t much of an issue since we don’t have any front facing websites that need HTTPS. Ideally, you’d want both covered under your certificate. Our app is the only thing accessing HTTPS and we can make sure https://www.nikywilliams.com is specified in the code. I’ve seen what looks like a few ways around this. 1) You’d have to get at least a Class 2 certificate so that you can secure both with and without the “www” prefix. 2) Find a way to redirect all https://www.nikywilliams.com requests to https://www.nikywilliams.com. I haven’t verified either way since it isn’t critical to what we are trying to accomplish. In any case, this is still a poor man’s HTTPS since we haven’t spent a dime!

Wrapping up Jumble Attack

This app was a particularly fun little project to work on for me. We introduced three new technologies as the main goal of this project was to figure out how to use those three technologies while still making a fun little game we could distribute. There were a lot of assets we were able to reuse from Shape Sprout so it made that part of the project go much more quickly. For our previous app, Shape Sprout, we included ads into our game using AdBuddiz which was relatively painless. For Jumble Attack, we added in-app purchases, data encryption and app-to-web server communication. The in-app purchases I think took the most time as they had to work on three different platforms: Apple App Store, Google Play Store and the Amazon Appstore. Each platform has a different way of allowing you to test those purchases without generating a real monetary transaction. Amazon seems to have given us the most trouble as the 3rd party plug in we were using, SOOMLA, has some issues with Amazon on their most recent update. We just went back to a previous version and all was well in the world. SOOMLA is actually pretty straightforward when integrating with the Unity platform and I have really enjoyed it so far, you can’t complain much for an open source plugin like this.  The setup required to make the in-app transactions happen can become pretty confusing; pretty soon I’ll have three new blogs on how to setup a store in Unity for each of the platforms, how we did the encryption and what we did to make the app-to-web site communications happen…including the extra steps you have to take when you want app-to-web site communications when playing your game through the Unity Web Player.  All very interesting stuff. We are in the last stages of testing Jumble Attack and hope to have it in the app stores very soon. We already know what our next project is going to be, so if you like cards, we know you’ll like Kung Pow Cards!

What do you mean I have to be “properly authorized” to use encryption in my apps?

09-08-2014

This took me by surprise. I remember seeing something while submitting previous apps to iTunes asking if I used encryption in my app but I had not noticed it on Google Play or the Amazon App Store (which there is a checkbox for it, it just hadn’t registered with me since I wasn’t using encryption). I hadn’t needed any sort of encryption until now and that got me asking questions about WHY Apple would want to know this. After digging a bit, I discovered that you have to be “properly authorized” by the  Department of Commerce (DOC) Bureau of Industry and Security (BIS) to use encryption in your app. Personally, I think it just needs to be shortened to BS. It’s only my controlled data and it does not contain any personally identifiable information, so why does the government need to be involved? So, anything that uses technology like HTTPS, DES, AES, etc. falls into this category. However, one way hashes like an MD5 don’t appear to fall into this category because it isn’t meant to be decrypted…I need to get verification on that one. So began my journey of trying to figure out what kind of paperwork was needed to get this going so we could be legit and I could use encryption in my app. I had found some resources online but they were a few years old and a lot of the links were broken. I was seeing acronyms like “SNAP-R”, “ERN” and “CCATS” but had no idea what exactly they meant. So I hit Google with the few leads I had and discovered that I needed to start with the “SNAP-R” system. No idea what that acronym meant so I looked it up; it stands for the “Simplified Network Application Process – Redesign” system…yeah, that really cleared things up. So I started there to try and get registered.

https://snapr.bis.doc.gov/registration/Register.do

Filled out all the information on the page (which wasn’t that much) and submitted it. It then told me that instructions would be sent to the email I specified and I MUST follow them. About 5 minutes later, I got my email and it said they were processing my information and should have it done within 5 business days. Not too horribly bad so far. I still don’t know what “CCATS” is exactly, but it sounds like it’s a more in depth process of getting “properly authorized”. From what I’ve read so far, I should only need to get approved to get into this “SNAP-R” system so I can apply for an “ERN” (Encryption Registration Number) so then I can submit the “ERN” to Apple to prove that we are “properly authorized” by the DOC. My head hurts now, maybe by the time they approve our “SNAP-R” application, I’ll be ready to tackle the next step…whatever that is.

09-09-2014

Woke up this morning to see an email about our “SNAP-R” registration. They sent me an “Applicant ID” in the email and a link I could use to verify my “SNAP-R” user account. Once I clicked on that link, it said I was verified once I entered in some information (don’t forget your password here) and then it then directed me to the following link so I could log in.

https://snapr.bis.doc.gov/snapr/exp/UserLoginLoad

Looking at this page, it asks for a “Login ID”, a “Password” and a “CIN”. It appears that both the “Login ID” AND the “CIN” are the same as the “Applicant ID” you received in the email. I believe at one point there was an older system in which the “Login ID” and the “CIN” were two separating things, it doesn’t appear that way anymore. So once you enter that info and log in, you are able to create a “work item” in this system. So, what does access to this “SNAP-R” system and these “work items” give us? Here is a definition from the site:

An important note in SNAP-R is that the term Work Item is used to refer to any of the BIS work related transactions that can be submitted online. These include: 
  * Export License applications 
  * Re-Export License applications 
  * Commodity Classification requests 
  * Encryption Registrations 
  * Agriculture License Exception notices

It is that “Encryption Registrations” part we need to register for to get an “ERN”. So after clicking on the “Create Work Item” link from the left part of the screen, it asks what we want to create and to give it a reference number. Select “Encryption Registration” from the drop down box and for a reference number, it has to follow the format of AAA9999. Since we are trying to get an “ERN”, I chose to use ERN as the alpha part and a random number for the number part. Then click on create…to fill out more paperwork. Filling out the next page isn’t too bad either, but I did have to find and fill out a “Supplement No. 5 to Part 742“, so off to Google to find out what that was. Clicked on a link I found on www.bis.doc.gov, and was greeted with the following message.

Does this seem ironic?
Does this seem ironic?

So a copy of the document for encryption registration is on an HTTPS server that appears to be self-signed. That just seems rather odd.

 

 

 

 

 

After locating the section we needed, I began filling it out. Again, it wasn’t too bad but it took a little while to do. Now that this paperwork is done, we have to export it in .PDF format and attach it to our work item at the bottom of the form. After giving everything a once over again, I clicked the “Check for Errors” button and it didn’t seem to find any issues. Then I spent the next 30 minutes trying to figure out HOW to submit the form as it wasn’t very clear to me since there was nothing like a visible “Submit” button on the page. When all else fails, start clicking other buttons to see what happens. I discovered you have to click the “Verify Address in Work Item to Submit” button at the bottom of the page right beside the “Check for Errors” button first. Then click the “Preview Work Item to Submit” button on the next page, and finally the “Submit” button shows up at the bottom of the next page. Once you click that button, it asks you to acknowledge that you won’t be able to make any more changes to the document once submitted. Okay, done and done.  When I looked back at my list of work items, the status was already “Accepted” for that particular “work item”. Not sure exactly what that means, I guess I’ll just wait on correspondence on how to get my “ERN”.

10 Minutes Later

Well, that didn’t take too long, only 2 days. Received an email saying I had a message in the “SNAP-R” system waiting for me. So I go to my messages and in there it has my new “ERN”. The process as a whole wasn’t horribly painful, just frustrating in trying to figure out everything that you need while reading all the legalese as I’m not very fluent in that language. Hopefully this is all Apple will need to verify we are now “properly authorized” to export or reexport encryption products. Guess we’ll find out when we are done with our app!

Some final thoughts about “Shape Sprout”

“Shape Sprout” is now live on the Amazon Appstore, Google Play StoreApple App Store and on Facebook! We are constantly learning new things every time we work on an app and at the same time, we find more ideas for other apps!  Apple took a little longer to approve our app this go around than it did last time…10 days. Amazon was only a day or two and Google and Facebook were pretty much same day. All in all, I thought the development of this app went exceptionally smooth. Very few bumps in the road from the development side…I just have to get my artistic ability up to par. Practice, practice, practice! And of course having Kari record audio for our games is such a blast; she always makes me laugh. We’ve already started development on the next app; it’s called “Jumble Attack” and is based on the hot air balloon event that happens in “Shape Sprout”. We decided on a bit simpler app this go around because we are changing how we are doing a few things and wanted to focus on getting those ironed out while still making a fun game to play. We’ve decided to go the in-app store route to allow people to purchase an ad-free gaming experience instead of having two versions of our game.  This should make maintenance a whole lot easier. Also, there will be some communications between our app and our web server. This is something we’ll use in later apps and wanted to see if we could find a good way to do that. We decided on doing HTTPS + encrypted data…then realized we have to get an ERN from the government before we could legally make an app available that implemented encryption or even used HTTPS. This was a surprise to us. Curious how to get your ERN? I’ll be posting how I did that very soon. The whole process only took about 2 days which is saying something when the government is involved. Onward and upward!