Home » Uncategorized

Category Archives: Uncategorized

Encrypting passwords in AppEngine

About this tutorial

This post explains how to encrypt passwords in order to implement a login system in AppEngine.

When we set up a login system our main concern is security. After all this is what login systems are about. And security means making it as hard as possible for a hacker to fake the system in order to get information from other users. In the world of information security the ability for our app to resist hacker attacks is called resilience.

Most of our efforts regarding resilience should be addressed to make it hard for the hacker to find out the passwords in case he’s able to gain access to the users database. And a great way to achieve this is by encrypting the passwords.

Enough obvious introductions, since this post intends to be eminently practical. Those interested in deepening further in this fascinating world can skip the remainder of the post and go directly to the excellent article by Brian M. Hunt Storing passwords using Python which in turn is based on the theory explained in the Q & A about Information Security from Stack Exchange.

What are we building

We’re going to publish the necessary services to store encrypted passwords and to verify the validity of a user-password combination.

The guys above have performed 95% of my task, so my job was reduced to some adaptations in order to make it work in a real app. But since these adaptations took me quite a few hours I’ve thought this post might be useful for someone else. My humble contribution can be summarized as:

  • Create the full datastore model for users database
  • Create the set of services necessary for accessing to the datastore from a client app
  • Wrap the services so that they can be called from a JQuery client
  • Solve some issues at the time of using the pycrypto library in Windows

Some screenshots

loginae02.png

As we can see, the sources contain a test page where we can try our services. We’ll typically follow 3 steps:

  1. Create a user including its password among other information
  2. Verify the user can login with this password
  3. Inspect the datastore in order to check how information is stored

Download

PENDING

How to install

The steps to follow are the usual ones for any AppEngine project:

  1. Download the sources in any folder
  2. Create a project in AppEngine Console (https://console.cloud.google.com/)
  3. Edit the app.yaml file in order to indicate the name of the project you’ve just created
  4. Deploy the project (e.g. using AppEngineLauncher or typing py update . from the folder you’ve created in step 1)

At this point, you should be able to execute the test page in the URL:

 http://projectname.appspot.com/html/test.html

If you have any problems with the installation, the post (PENDING) contains some more details.

Once the installation is ok, you should delve into the sources in order to understand the code and adapt it to your specific needs. At the time of testing the services locally you may encounter some problems with the pycrypto library as it happened to me. If this is the case, you can have a look at this post (PENDING) where I explain several ways to solve them.

How it works

All the encryption stuff is encapsulated in the encrypt.py module, which is copied with nearly no modifications from the afore mentioned M. Hunt’s post. The algorythm is perfectly explained there so I’ll simply show the code:

This code should work for you without any adaptation, but you should pay attention to the ITERATIONS_2015 constant since it determines the hashing speed and hence the time it takes for the user to log in. Take into account that hashing must be slow for the system to be secure, but you can of course decide how long are your users willing to wait. In my case, I’ve made it slightly faster than current recommendations. Theoretically, you should make this adjustment only once since the algorythm increases the iterations periodically as a counterpart to growing computation power. However, you’ll probably want to review it from time to time based on real experience.

Once we have the encryption module, developing our services is fairly easy. First off we’ll define our user’s datamodel:

class User(ndb.Model):
  username = ndb.StringProperty()
  password = ndb.StructuredProperty(Credentials)
  name = ndb.StringProperty()
  mail = ndb.StringProperty()
  icon = ndb.StringProperty()

Notice we could have integrated User and Credential entities into a single one since we’re actually going to access to them together. However, I decided to maintain them separate because it can eventually allow me to reuse Credentials in other systems.

Now let’s see how to add a new account:

  newuser = User();
  newuser.name = name
  newuser.username = acct
  newuser.mail = mail
  newuser.icon = icon
  c = Credentials()
  c.set_dk(pw)
  newuser.password = c
  pkey = newuser.put()

And this is how we can validate a user – password combination:

  acct = self.request.get('username')
  pwd = self.request.get('password')
  results = User.query(User.username == acct).fetch(limit=1)
  if len(results) > 0 :
    c = results[0].password
    if not c.verify(pwd):
      # ok
    else:
      # error 

And that’s all. Of course I’m omitting the validations and other stuff. You can find everything in the code any it should be trivial to understand, but if anything remains obscure I’ll be pleased to clarify it. Just a couple of final remarks about the implementation:

  • The services are prepared for being called from a JQuery app. For this reason, if they are called with a “callback” parameter, the response includes this parameter in the format expected by JQuery
  • For debugging convenience, services can be called indistinctly via GET or POST. In your real app, you’ll definitely prefer to enable only POST. This is as simple as removing the get function from each class.

Further ideas

The whole login system has a great deal of possible enhancements, which are mentioned in the post (PENDING). As for the specific ones concerning password encryption, I’ll simply address you to those mentioned by M. Hunt in the  post used as a reference:

  • Keep track of failed attempts (and take some action once a certain threshold is surpassed
  • Store a list of computers (or IP addresses) authorized and perform the corresponding validation when a login is attempted
  • Two factor authentication as an additional security mechanism for critical operations. Particularly, Mobile two-factor authentication is currently receiving great attention and it would be a nice enhancement for my apps
  • Avoid storing the iterations and salt with the derived key (since the hacker will probably gain access to all of them and his decryption task will be eased)

I think Hunt’s job is already excellent without this stuff, but we’ll have to be attentive to his progresses.

Advertisements

A jQueryMobile real app

About this tutorial

The posts in this site have a different degree of detail when compared to most tutorials. I mean such tutorials use to provide the full code with detailed explanations but, for a matter of space, they do not build full applications. So they are very useful to find the solution to specific problems but fail to cover the nuts and bolts for passing from a prototype into a production application. On the contrary, this site intends to help people solve real issues faced in practice, and the best way I know to achieve this goal is presenting a real app and explaining how the trickiest issues were solved.

This broader scope comes at the cost of less detailed explanations, but my goal is to provide enough information for an intermediate reader to understand the module and be able to build or adapt it on his own. However sometimes it’s difficult to find the right balance so if anyone is interested in any clarification please leave a comment or contact me and I’ll be pleased to answer. Also remember that all details omitted in the explanations can be discovered by inspecting the sources.

What are we building

The app was born as a school entrepreneurship project. The requirement was to develop and publish a marketable app that could potentially attract thousands of downloads. The latter part is not achieved yet, but I’d like to think the pending job is more commercial than technical, so that shouldn’t bother us for the moment.

The app is intended to help tourists enjoy the visit to a city. It’s initially prepared only for Barcelona but it should be easily adaptable to any other city. As a differentiator factor, we decided the app should be very “social”. We’re going to see its three main aspects:

  • Chat system: allows users to contact each other in order to ask questions, organize meetings, etc. There is both a general chat and a specific one for each event and attraction. The user can “like” an answer so that best comments can be easily spotted
  • Events page: it’s maintained dynamically via a spreadsheet. The user can join any number of events and as a confirmation the app sends him an automatic email with an itinerary attached
  • Login system: the user can optionally identify himself into the app. Some options are only available to identified users as a way to enforce some kind of commitment

The app has also some static content, but we’re not going to see it since it’s quite trivial to create. The sources provided do not contain this content so we’ll obtain a somewhat simpler app than the real one.

Some screenshots

jqm21

Download

Client app: Sources of JQueryMobile app, including both HTML, Javascript and static resource files Download
Server: Sources of the server side. This is python code and some static files ready to be published in AppEngine Download
Standalone version for web: If you want to have a quick look at the app, here is a (somewhat different) version for web Try
Google Play app: The fastest way to test the app in your mobile, but of course you’ll miss the chance of enjoying its development! Download

How to install the app

The sources downloaded should allow you to run the app both in your computer and in your phone, except for the following considerations:

  • The chat will point to a demonstration server. You must inform your server URL editing the touristapp.js file located in the client /js folder and changing the SERVER_URL variable
  • The events page will show some demonstration events. You can create your own events via a googledocs spreadsheet as explained in the Integrating Google forms with JQM post

Once this is done there are many ways to execute the app. You’ll probably have your own method, but just in case here is a summary of the methods I use depending on my needs:

Server: After downloading the zip file, there are typically to ways of testing it:

  • Rapid try&error changes: unzip the server file into any folder and then start appdevxxx on that folder or open AppEngine launcher and create a project pointing to it (see instructions). If you use this option, you’ll have to inform the assigned URL (typically something like http://localhost:20080) in the SERVER_URL variable indicated above
  • Once you’re sure everything is ok: use appdevxxx or the Deploy option of AppEngine launcher.

Client: After downloading the zip file you can test it in several ways:

  • Interface tests: unzip the client file into any folder and double-click at the index.html file. The app will be shown in your local browser but without functionalities (e.g. if you go to the events page you’ll get a never ending “Loading…” message
  • Rapid try&error changes: unzip the file into the web server directory. For example, if you’re using an Apache web server you’ll typically have an httdocs folder, so you need to unzip the app into this folder and type into the browser the URL http://localhost/touristapp_client
  • Local mobile (rapid mobile test): once you’ve done the previous step, if you plug your phone to the computer you’ll be able to run the app into the mobile browser by typing the URL assigned to the connection (e.g. 92.168.1.106/touristapp_client)
  • Once you’re sure everything is ok: Generate the executable file and copy it into your phone. The way to do this will depend on your device, but you may want to try Phonegap, specially the cloud service that allows you to generate a multiplatform app without need to install anything in your computer

In case you have any doubts, this video explains a simple way to publish an app in Google Play using Phonegap to pack it in the Android format (.apk).

How it works

Finally, let’s go to the code. In order to keep this post to a reasonable extension, the explanations are organized as separate links. They are more or less independent so if you’re just interested in one topic, it should be possible jump directly to it. However, I’d recommend having a look at the first post to understand the app architecture.

  • An architecture for JQM with APPENGINE
  • Integrating Google forms with JQM [PENDING]
  • A chat service for JQM [PENDING]
  • A login template for JQM [PENDING]
  • Some nice APIs for JQM [PENDING]
  • Tips and tricks [PENDING]

Further ideas

The current app requires an internet connection to work properly, but the architecture is prepared to overcome this restriction. The post An architecture for JQM with AppEngine explains how to adapt the current app in order to provide offline capabilities.

Life beyond App Inventor

I made my first steps in mobile app development with App Inventor, and I was surprised to discover it was far more powerful than I had initially suspected.

Anyway, the environment has some limits. My latest experience has been translating an app from AI classic to AI2, and I’ve been pleased to realize some of these shortcomings have been overcome (local variables, several screens at design time, integrated block editor…). That’s a good job, but there are some structural aspects remaining and I don’t think it’s in the evolution plan to overcome them. The two key points are:

  • Limited possibilities regarding graphical design
  • Restriction to Android devices

I recently needed to surpass these limits and started looking for alternatives. I tried the whole spectrum ranging from direct java programming with Eclipse to popular frameworks such as Angular JS, Phonegap and Sencha Touch. Rather than discussing the pros and cons of each one, let’s open directly the envelope. And the winner is… JQuery Mobile!

jqm_03

The best way I can find to demonstrate the framework strong points is to explain the experience with my first JQM app. It was actually my 14-years old son who developed the app for a school project, and I just had to complement it with some programming – mostly shown in the JQM page. And no, unluckily I’m not the parent of a new Zuckerberg. He’s got zero programming skills and just a basic knowledge of HTML acquired at school. I know this is the perfect profile for an AI user and he’s actually quite fond of it, but in this case multiplatform and a rich graphical design were necessary issues.

I’ll use this experience to exemplify the three stronger points I find in JQM:

  • Ease of learn and use: For those who are new to JQM the learning curve is quite low, although it will obviously depend on your background especially in HTML5 and Javascript or similar. For example I was not very familiar with them but I had a good knowledge of HMTL and Java, which simplified my learning process
  • Ease of deployment: JQM is inherently portable to any platform supporting HTML5 and from here there are several ways to deploy it in all currently dominating platforms. For example, here’s a video showing the steps to follow for publishing an app in Google Play (and mostly valid also for any other platform)
  • Documentation: A vast community of users maintains an extremely dynamic source of knowledge. Whatever doubt you have, just think of a way to express it in two words and type in Google JQM followed by these two words. There are 90% chances for the answer to appear in the first page. You should first choose the Stackoverflow answer, usually accurate and effective.

In sum, for those who feel AI is falling short for any of their projects, I’d consider JQM as a good alternative. To get started, I’d recommend you to visit the JQM demos site and then follow a tutorial such as the JQM tutorial.

So, thanks a lot to the guys from the MIT for the great moments with App Inventor. I suspect my next steps will be with JQM but AI will be forever in my toolbox and I’m pretty sure I’ll go back to it in future projects. When this occurs I’ll be pleased to add new posts in this site so as to increase my humble contribution to the AI community.

How to adapt to screen orientation in App Inventor

Introduction

NOTE:

This post was initially published for AppInventor classic, but currently sources are available also for AI2. However, I have not updated the comments and images because the code is roughly the same.

This post explains a mechanism to resize the visual components when the screen device changes its orientation (i.e. from vertical to horizontal or vice versa). The objective is to avoid that these components get out of view when the screen height or width is shorter than in the original design.

It’s important to remark that the technique explained in this post can be adapted to achieve other purposes such as those mentioned in the Further Ideas chapter:

  • Adapt the components size in order to fit in the screen for devices with different size
  • Provide multilingual capabilities to an app

What are we going to build

We’ll typically design our app with vertical orientation, so when the orientation changes we need to “flatten” the design. For example, the app we’re going to follow contains a menu screen designed in a vertical layout to show 4 square buttons and a small button below (see image), but when orientation changes this shape provokes the lower buttons to disappear from the screen. Our solution converts these buttons into rectangles in order for them to fit in the screen.

logintutorial_72

Of course this adaptation is not always necessary or desirable. Actually you’ll probably want to avoid it for textbox components because reducing its original height is not likely to be a good idea.

Instead of resizing components, we could consider the option of moving them (fpr example the central screen in the image would be perfectly valid if we were able to place the small red button in the empty right side zone). However this would be nearly impossible in AI because the components’ position attribute is not modifiable by code (it’s rather assigned automatically). Maybe a solution based on hiding and showing arrangements could be an idea to explore but I’m not sure this would really work.

How it works

The idea is to divide the screen in an imaginary grid, with each component being fully located in some of the resulting cells and taking into account both orientations. In our example the grid could have a size of 9 x 11 which would give the following appearance in both orientations:logintutorial_71

This division allows the algorithm to work out the X and Y position of each component by multiplying the left-top position within the grid by the width of each cell and the same for the Y position.

For example, if our screen size is 440 x 270, the button’s position would be:

  Cell Size Blue button Cyan button Green button Yellow button
Horizontal 30 x 40 (60, 80) (180, 80) (60, 240) (180, 240)
Vertical 40 x 30 (80, 60) (200, 60) (80, 240) (200, 240)

Installation

You can try the application by downloading these sources and uploading them into App Inventor. You’ll realise there’s some functionality that is not explained in this tutorial because this is actually a more general application (which is explained in the Login template post). The part that concerns us is just the menu window.

User interface

logintutorial_15 logintutorial_16

The components are very simple. No secrets with buttons: one for each option and an additional one for “Exit”. Labels are somewhat trickier because they’re used to leave some space between buttons. The TableArrangementMenu1 has 4 columns and 5 rows and the labels are positioned in:

  • Label1_3: Row 1, Column 3
  • Label_3_1: Row 3, Column 1
  • Label_5_3: Row 5, Column 3

To achieve the layout required, you can specify the desired height and width for these labels. However, these attributes will be overridden by code.

Code blocks

Variables

logintutorial_73

  • iScreenHeight, iScreenWidth: Store the screen height and width. They are updated at initialization time and each time the screen orientation changes
  • iHeight, iWidth: Auxiliary variables

Functions

logintutorial_74

  • Screen1.Initialize, Screen1.OrientationsChanged: These are the two events that concern us, as they are the points when the initialization of components size takes place by means of a call to the initMenusize function
  • initMenuSize: This is the actual function that places the components according to the screen current size. Since we cannot indicate the position, the secret consists in specifying the height and width for both the buttons and the spacer labels strategically placed between buttons (see above). The calculations should not be difficult to understand if we have the grid image in mind. Note that the example above was simplified so the numbers in the code are slightly different. For example the buttons occupy 3 x 4 cells (rather than 3 x 3) and the screen is divided in 13 x 11 cells (rather than 11 x 9) because we have some extra space occupied by a header bar. I advise you to experiment different combinations to fully understand the algorithm.

Further ideas

The work we’ve done in this tutorial can be a first step to achieve other useful functionalities. In this final chapter I expose a couple of such extensions that I’ve developed and are explained in this tutorial.

Adapt components size to different devices

Supporting different devices without having to create different versions of the app is probably a much more common requirement than adapting to orientation change. The good news is that our technique is quite close to the solution. For example, the menu built in this tutorial would be correctly displayed in a larger device such as a tablet. For the whole app to be smartly presented we must simply adapt the initMenuSize function in order to apply the same resizing technique to all of our compoments. Of course this would be much more tedious, so rather than explicitly indicating each component in the function, we must previously create a  list of components, and loop through this list in the initMenuSize function. This is not a five minutes task so please refer to the above mentioned tutorial for the details.

Multilingual capabilities

Similarly, if we intend our app to be able to “speak” several languages, we won’t obviously want to rewrite it for each supported language, but rather think of a means to modify the text of captions and labels at initialization time in order to show them in the language chosen by the user. Once again the idea is looping through all components in an initialization function, in order to set the caption corresponding to the current language. The captions mst be obtained from a list populated at design time and stored for example in a TinyWebDB component. Another fascinating project that deserves a tutorial on its own.

An optimal way to manage multiple windows in App Inventor

Introduction

NOTE:

This post was initially published for AppInventor classic, but currently sources are available also for AI2. Unless explicitly noted, comments and images correspond to the classic version but the code is roughly the same.

I have to admit that the method we’re going to explain is not so advantageous in AI2 because now it’s possible to edit several screens at development time, which was one of the two main weak points in AI classic multiscreen. Anyway, the drawback of not being able to share variable and methods remains, and I think that’s enough reason to use this method is most of our projects.

This post demonstrates a method for managing multiple windows in App Inventor based on hiding and showing arrangements from the same screen. I admit the title may be controversial, but I’m really convinced that this is the most effective way to manage multiscreen in the AI current state of art. Anyway I understand this is arguable so if you’re not comfortable with the title just think of this tutorial as an “alternative method to manage multiscreen” which you could consider in some of your apps.

What are we going to build

As we know, release 42 of AI added support for multiscreen, recognizing it as an absolute necessity for any app that goes beyond a simple prototype. So before release 42 we were forced to simulate multicreen by showing and hiding controls. And now I’m proposing to go back to those times (!). Well, let me clarify it. What I’m proposing to do is avoid creating a separate screen for every window you want to show. The reason is that current AI screens have two main drawbacks:

  • You cannot reuse anything among different screens. In other words, you cannot share functions and controls that are common to all screens (you’re forced to replicate them in all the screens). For variables this is somehow mitigated because it’s possible to pass values, but for functions it’s really tedious and a great source of quality problems. We’re still lucky to count on the excellent copier facility provided by the App Inventor Repository, but this helps only when creating the app and not for its further maintenance (which consumes 80% of development time in traditional environments and probably more in AI)
  • You cannot switch forms while testing in the development environment, so it’s not possible to test interaction among screens (you need to generate a version each time)

By including several windows in a single screen we avoid both problems: you can test the windows interaction while developing and you can have a shared version of variables, functions and components that are common to all windows. It has also drawbacks, from which I’d remark two:

  • The design task is more complicated because all the windows are mixed and it’s harder to see the real appearance of each one
  • You have to manage the transitions between screens (particularly the back button)

For the first issue I recommend to mark all windows as non-visible except the one we’re working on. This way we can concentrate successively in the different windows and work in the same conditions as if we were using separate screens. Hidden windows are not a problem for testing because they are appropriately shown by code (as we’re going to see).

Regarding the second issue, that’s precisely why I’ve written this post. We’ll see a method to handle windows transitions in a systematic way. It may appear complex but we must take into account that part of this code would be necessary anyway if we used separate screens. Moreover, it would be replicated in every screen. On the whole, the code for the same app would be considerably longer (I know it very well because the app was initially written with separate screens!).

How it works

The key for simulating the screen transactions is a well known pattern called stack (technically a LIFO stack, which stands for “Last In First Out”). For those who have been around the programming world for some years this pattern leads us back to the hard origins when we were forced to program in machine code primitive computers such as Sinclair Spectrum. The pattern idea is to pile up an undetermined number of events (in our case the windows shown) but at any point in time we need only to be aware of the last event. The solution consists in using an infinite stack (which in AI can be implemented with a list) where we add and remove elements, and maintaining a pointer (a numeric variable in AI) indicating which is the last element from the stack.

This is more clearly shown with an example. Imagine the user logs into the application, pushes the Register button and from here the Help button. Then he presses twice the back button which must bring him back to the login window. The following image depicts the contents of the stack after each event, the red element indicating the currently shown window:

logintutorial_61

As we can see, after pressing the back button we must simply remove the top element and get the new top in order to locate the window to show.

Installation

You can try the application by downloading these sources and uploading them into App Inventor. You’ll realise there’s some functionality that is not explained in this tutorial because this is actually a more general application (which is explained in the Login template post). The part that concerns us is the way to implement seven windows using just two screens.

User interface

Each window to show must be simulated by means of a TableArrangement component. If this kind of arrangement is not suitable for the layout required in our window we can simply add the right arrangement under the TableArrangement. For example, the following image shows a window that requires two arrangements (Horizontal and Table):

logintutorial_62

Therefore our graphical design task consists in distributing each component into the TableArrangement where it must appear. The Arrangements’ Width and Height attributes will typically be set to “Fill parent”.

Code blocks

CONSTANTS

logintutorial_63

  • SCR_LOGIN, SCR_REG, SCR_SEND, SCR_HELP, SCR_GOOGLE, SCR_MAIN: We associate a numeric value to each window in order to make the code more readable (e.g. the sentence “CurrentScreen = SCR_MAIN” is much easier to understand than “CurrentScreen = 1

VARIABLES

logintutorial_64

  • lstStack: List of open windows. This is the stack used to control the back navigation
  • iStackPointer: Pointer to the current screen within lstStack
  • lstScreens: List of TableArrangements used as containers to simulate windows. The fact that all elements in the list have the same type allows to make generic calls to obtain an element and show it, which is the key for the pushScreen, popScreen and ShowScreen auxiliary functions

INITIALZATION FUNCTIONS

logintutorial_65

  • Screen1.Initialize: The only meaningful part is the call to function initScreen and pushScreen. Other sentences are not used in this tutorial
  • initScreen: Initializes the lstScreens variable with the table arrangements used to simulate windows. The order is very important, because the table correspondiing to each window is located by position in this list. For example, to obtain the Register window we must use the sentence:

SELECT LIST ITEM lstScreens, SCR_REG

USAGE FUNCTIONS

The mechanism to open and close windows is as simple as it would be with screens. Here are a couple of examples:

logintutorial_66

  • ButtonRegister.click: Any action that requires opening a window needs just to call the pushScreen function passing as a parameter the constant value assigned to the window
  • Screen1.BackPressed: Call the popScreen in order to remove the top window from the stack and show it. If the stack is empty close the application

Of course for this simplicity to be possible we need the auxiliary functions popScreen, pushScreen and those related.

AUXILIARY FUNCTIONS

logintutorial_67

  • pushScreen: This function receives as a parameter the window to open. It adds the window to the stack, hides the current window and shows the new one using the ShowScreen auxiliary function
  • popScreen: Obtains the window that is on top of the stack and hides it. Then removes it from the stack, obtains the previous one and shows it using the ShowScreen auxiliary function. It returns the currently visible window
  • getCurrentScreen: obtains the screen that’s currently being shown (i.e. the one on top of the stack). This function is called from the initHelp function in order to initialize the help texts taking into account the current window. The function returns directly the iStackPointer value so it does not save space but using a function is smarter and eases evolution in case the stack implementation changes some day

logintutorial_68

  • ShowScreen: This function receives as a parameter the index of the window to show. It then retrieves the associated TableArrangement from the lstScreens list and makes it visible. That’s all regarding the graphical stuff, but this function is also the equivalent to the screen’s Initialize event so it’s the place to handle specific initialization events. In this case:
    • Enable a timer in case we’re showing the Google window (and disable it otherwise)
    • Hide the top bar in case we’re showing the Google or Help window
    • Show the Profile button only in case we’re showing the Main window
  • ShowMain: This function is called to show the main menu. An important aspect to remark is that once in this window the back button is not supposed to go to the previous window but rather to close the application, so the function empties the stack before pushing the Menu window into it.

A simple way to encrypt texts with App Inventor

Introduction

NOTE:

This post was initially published for AppInventor classic, but currently sources are available also for AI2. However, I have not updated the comments and images because the code is roughly the same.

This post explains a simple method to encrypt/decrypt a text using exclusively the functions provided by App Inventor, i.e. without need to call a specialized library. One of the advantages of using only client code is that it does not require an Internet connection to work.

An encryption algorithm is a function that applies a certain transformation (encryption) to an input string in order to obtain an output string which can afterwards be transformed again (decrypted) in order to get back to the original string. Encryption algorithms are usually public, but (in theory) only the encrypter system is able to perform the decryption because the transformation algorithms use a secret key only known by the system.

The reason for building the solution explained in this tutorial is that I could not find one that met my requirements. As explained in this post from Google Groups, we can consider 3 ways to implement encryption in AI:

  1. Call a server side library using the StartActivity component. The AI Extensions mentioned in the same post seem to be an excellent choice for this purpose
  2. Use javascript in the client side. This is based on the clever idea of downloading such scripts in the first run as explained this post from Puravida
  3. Program your own algorithm using AI code blocks. One solution for this is the Encryption and Decryption v3 from Abacus apps.

I didn’t like the first solution because in my case I have the original text in the client side so it looks safer sending it already encrypted to the server. The second option meets this requirement but I was not comfortable with relying on javascript and additional downloaded files. So I decided to try the third approach, which is the one explained in this utorial.

Next question is why not the solution mentioned in the third point. Well, there are three reasons for that. The first one (and to be honest the real reason) is that this solution was not posted when I needed it. The second reason why my solution might still be useful is that it’s so simple that it has immediate response time whereas it seems the mentioned solution can take up to 22 seconds as explained in this post. The final reason is that this site intends to provide some instructive material that helps intermediate readers improve their skills on AI and development in general, and I hope the post can be useful in this sense regardless of whether the results is used.

That being said, if you’re lloking for a more sophisticated solution developed in App Inventor you should refer to the solution mentioned in the third point which will probably have more support and evolution than my humble contribution.

What are we going to build

The method is inspired in standard encryption principles but with several workarounds to overcome the lack of some functions in App Inventor. Actually it is simpler to program than to explain, so maybe you’ll prefer to skip next section and go directly to the code or to the example below. Anyway for those interested I’ll try to explain the theory behind this code.

How it works

We’re going to implement a symmetric encryption algorithm, i.e. one that uses the same key to encrypt and decrypt. A usual means to achieve this is the XOR function because it has the property that XORing a data twice with the same key results in the same data. The XOR function receives two arguments (in our scenario the input string and the secret key) and obtains the output by comparing each bit from the two arguments and generating a 1 for different bits and 0 otherwise. For example, if the input string is “ac” and the key is “12” we would do the following:

logintutorial_51

So the output string would be “PQ”. Now we’ll apply the same algorithm to obtain the original string:

logintutorial_52

Unluckily App Inventor does not provide the XOR function (see related issue) nor bitwise manipulation functions that would allow simulating it. So we’ll use a substitute mechanism: create a string containing all the possible characters of the input string, and substitute each character by the opposed in this string, i.e. substitute the first character by the last one, the second by the last but one, etc. An example is simpler to understand: if the allowed characters are “aeiouAEIOU” and the input string is “aA” then the output string will be “Uu”. Notice that if we apply the same transformation to the string “Uu” we obtain again the original “aA” string.  This way we have a reversible function like XOR, but with this alone our encryption would be very weak because anyone reading this tutorial (or with some imagination) would be able to decrypt it. That’s where the key comes into play. What we’ll do is “disorder” the allowed characters string by placing at the beginning the characters of the key. For example if the allowed characters are aeiouAEIOU and the key is “aEiO” we’ll generate the encrypter string “aEiOeouAIU

Installation

I have no isolated sources for this tutorial because its implementation is embedded into a more general application (a “Login template” that uses encryption to store passwords). So if you need to implement this algorithm you can either type the code looking at the images below or download the whole sources of the login template. By the way, if you’re interested in the template you can have a look at the Login template tutorial.

User interface

I won’t show the graphical part of this functionality because it’s mixed with other controls so it would be difficult to show separately the specific components. Moreover, the interface has no secret: if you want to a make a quick test you just need to create a screen with two textboxes (for the input string and the key), a button (to perform the encryption) and a label (to show the results).

So let’s go with the code!

Code blocks

Before seeing the encryption and decryption functions, let’s have a look at the required initializations:

logintutorial_93

Constants

  • ALPHANUMERIC_CHARS: A string composed by all the characters that can appear in the input string. You can add or remove characters if you wish to
  • CRYPTO_KEY: Your specific key. You SHOULD change its value. You can use only characters contained in the ALPHANUMERIC_CHARS variable. The string can have any length, but it’s advisable for it to have at least 10 characters. You can repeat the same character several times in the key, but only the first one will be taken into account

Variables

  • sEncrypterKey: contains the key string used by the encrypter and decrypter algorithms
  • sVal, sRet_xor: auxiliary variables

Initialization functions

  • InitCrypto: This function informs the sEncrypterKey variable with the same characters as the ALPHANUMERIC_CHARS variable but disordered (i.e. the characters from CRYPTO_KEY are moved at the beginning). The code consists of a simple loop through the CRYPTO_KEY characters in order to move them at the beginning. Notice the “if” line which is used to ignore any repeated characters

Main functions

logintutorial_94

  • encrypt , decrypt: Yes, as easy as that! The output string is simply obtained by applying the pseudoXOR function to the input string
  • pseudoXOR: The “reversing” function. It’s based on a loop that reads each character from the input string and locates its opposed character within the sEncrypterKey variable.

Further ideas

The algorithm explained in this tutorial is very basic. It would not be very hard for an expert to decipher the key if he was able to capture enough couples of encrypted-decrypted strings. If you want to sophisticate it but don’t wish to recur to the above-mentioned more complex solutions, you can extend the code in many ways. For example we could add a random number of characters at the beginning and at the end of the deciphered string in order to mislead hackers. In this case, for the decryption to work we should also include a couple of counters indicating where is the real string. This is better explained with an example:

DATA
Input string: dog
Key: sample
Allowed characters: abcdefghijklmnopqrstuvwxyz
Previous characters: 1
Ending characters: 5
ENCRYPTING STEPS
1) Disorder the allowed characters string in order to obtain the encrypter string: samplebcdfghijknopqrtuvwxyz
2) Reverse the input string: qbp
3) Add random characters: wqbppoldw
4) Add two counters at the beginning: amwqbppoldw (see next point to understand it)
DECRYPTING STEPS
1) Obtain the real string. “a” is the second character in the encrypter string and “m” is the third. This means the real string starts at position 2 and has a length of 3, i.e. it’s the string qbp
2) Reverse the string: dog

To implement this variation we should modify the encrypt and decrypt functions in the following way:

logintutorial_56

A Login template for App Inventor (part 2)


Code blocks

NOTE:

This post was initially published for AppInventor classic. Currently sources are available also for AI2 but unless explicitly noted comments and images correspond still to classic version since the app is roughly the same.

This post completes the tutorial for creating a login template. In part 1 we designed the user interface. Now we’re going to add the code necessary for it to work!

The following image depicts the blocks for all the functionalities:

logintutorial_31

The blocks editor layout intends to be organized in a way that facilitates its comprehension:

  • Constants: Variables with an initial value that does not change. According to the standard programming convention their name is fully written with capital letters and the character “_” is used to separate words.
  • Variables: Variables that change over time. They are typically initialized in the initializations functions (see below). By convention they have a prefix indicating their type (s: text, i: number, lst: list, b: boolean)
  • Auxiliary functions: General purpose procedures shared by different functionalities
  • General events: Events captured during the screen execution

  • One column for each of the functionalities: Login dialog, Register dialog, Send password dialog, Goggle login interface, Menu

Constants

logintutorial_32

  • C_BLUE, C_CYAN, C_ORANGE, C_GREEN, C_RED: Some customized colors for the menu. For example:

logintutorial_33

NOTE: These colors are taken from the palette defined in the google style guide for android

  • C_BLUE_SEL, C_CYAN_SEL, C_ORANGE_SEL, C_GREEN_SEL, C_RED_SEL: Some more colors, slightly lighter than the previous ones. They’re used to change the menu option color when pressed.
  • CLIENT_ID, CLIENT_SECRET, RESPONSE_OK, RESPONSE_DENIED: Constant values for the Google Login functionality explained in the tutorial How to redirect to the Google login.
  • SCR_LOGIN, SCR_REG, SCR_SEND, SCR_HELP, SCR_GOOGLE, SCR_MAIN: We associate a numeric value to each window. This is used in the screen management tutorial to make code more readable (e.g. the sentence “CurrentScreen = SCR_MAIN” is much easier to understand than “CurrentScreen = 1
  • DATA_PWD, DATA_MAIL, DATA_SENDMAIL: We associate a numeric value to the fields stored in the database. This is used to make the code more readable (e.g. when this information is stored in a list we can obtain “SELECT LIST ITEM list DATA_MAIL” which is easier to understand than “SELECT LIST ITEM list 2”). This way, to add a new field to the database we simply need to create a new constant with a significant name and assign to it the first available number.
  • ALPHANUMERIC_CHARS: This string contains all the valid characters for both username and password. It’s used for validating the entered values and also in the encryption algorithm explained in the post A simple way to encrypt texts with App Inventor.
  • APPENGINE_ADDRESS, AUTH_KEY: The authenticator key and address for the mail sending service. They MUST be informed with the right value as explained in the post How to send direct mails
  • CRYPTO_KEY: A key used to encrypt passwords. You should change it to a value that only you know

Variables

logintutorial_34

  • lstStack, lstScreens, iStackPointer: Variables used to control the back navigation (see the post An “optimal” way to manage multiple screens)
  • lstUserInfo: A list containing all the information from a user: password, email, sendmail
  • iScreenHeight, iScreenWidth, iHeight, iWidth: Variables that store the screen size. They are used to calculate dynamically the dimension of some components (for example when changing the screen orientation as explained in tutorial How to adapt controls appearance depending on the screen orientation)
  • sCode, sResponse, sToken, lstResponse: Used in the Google Login window
  • sEncrypterKey: A string used by the encrypter algorithm. It’s calculated at initialization time by merging the constants ALPHANUMERIC_CHARS and CRYPTO_KEY
  • sUser: Stores the user that’s currently logged in
  • bLogged: Indicator of whether the user is already logged. It’s used to decide the behaviour in some places (e.g. make visible the User label at the header screen)
  • iIndex, iVal, sVal: Auxiliary variables used in several places
  • sRet_checkPassword, sRet_isAlphanumeric, sRet_xor: Return values for functions

NOTE: The latter variables are not necessary anymore in the version for AI2 since return value is solved by means of local variables (see below the code for the checkUsername function)

Auxiliary functions

logintutorial_36

  • initMenuSize: Used to set the height and width of menu options depending in the screen size. It’s called when initializing the screen and also when changing the screen orientation. The code is explained in the post How to adapt controls appearance depending on the screen orientation
  • popScreen, pushScreen, getCurrentScreen, showScreen, showMain: Functions used to manage the screens. They are explained in the tutorial An ‘optimal’ way to manage multiple screens
  • initCrypto, encrypt, decrypt, pseudoXOR: Functions used to encrypt/decrypt passwords. They are explained in the tutorial A simple way to encrypt texts with App Inventor
  • initColors: Used to apply the customized colors to the components. It simply sets the right Backgroundcolor attribute to each component
  • initScreens: Initializes the variable lstScreens with the list of existing windows

logintutorial_35

  • initHelpLabels: This function is called every time the help button is pressed. It sets the text labels of the screen buttons according to the currently selected window (which is received as an input parameter)

logintutorial_37

  • checkUsername, checkPassword: Validation functions that enforce some rules regarding the username and password format. The code is self-explanatory
  • isAlphanumeric: Auxiliary function that returns true if all the characters of the string received are alphanumeric (i.e. exist in the ALPHANUMERIC_CHARS constant)

In this case let’s see the checkUsername function both in AI classic and AI2, since it’s a simple example that demonstrates how to make our code cleaner and safer thanks to local variables:

logintutorial_90 logintutorial_91

General events

logintutorial_41

  • BackPressed: Manages the behaviour of the “back” button in order to simulate the window closing, as explained in the post  An ‘optimal’ way to manage multiple screens
  • ScreenOrientationChanged: Resizes controls according to the current screen height and width, as explained in the post How to adapt to screen orientation
  • OtherScreenClosed: Restores the components’ colors since they may have changed to improve user feedback.

NOTE: AI does not provide visual feedback when a button is pressed. This is annoying specially if the action associated to the button takes some time to initiate because the user may not be sure of whether he’s really pressed the button. That’s why we improve his experience by playing a sound and changing the color of the pressed button

  • Initialize: Calls the initialization functions, shows the login window, obtains default values for some fields (username and password) and redirects to Google Login if this is the default option

Login window

logintutorial_42

  • ButtonLogin.Click: Queries TinyWebDB to verify that the username/password exist in the database.
  • TinyWebDB_LOGIN.GotValue: Obtains the information about the user by means of the getUserInformation function (explained below). If password is correct shows the menu window calling the ShowMain function explained in the tutorial  An ‘optimal’ way to manage multiple screens. Additionally, if “Remember” is checked, stores the values entered in the TinyDB so that they become the default options for the device.
  • ButtonGuest.Click: shows the menu window calling the ShowMain function explained in the tutorial An ‘optimal’ way to manage multiple screens. This function receives the user as a parameter, which in this case is informed with the special value “_guest”. In further places a comparison with this value is used to limit the available options (e.g. disable the option to modify the profile)

Register window

This window is used both for the initial register and to modify the profile. In the second case the username textbox is disabled. The code uses this condition to skip some controls in case we’re just modifying information.

logintutorial_43

  • ButtonRegister.Click: Shows the Register window using the PushScreen function explained in the post  An ‘optimal’ way to manage multiple screens.
  • ButtonOk_REG.Click: Validates that username and password format and queries TinyWebDB to verify the username does not already exist in the database
  • TinyWebDB_REG.GotValue: After some validations stores the information in the database and closes the window using the popscreen function explained in the post  An ‘optimal’ way to manage multiple screens.

logintutorial_44

  • GetUserInformation: Auxiliary function that receives as input parameter a string of data separated by the characters “|||” (i.e. the way it’s stored in the database) and returns a list with an element for each piece encountered (e.g. the input string “myPwd|||myMail|||1” would return a list of 3 elements: [myPwd] [myMail] [1] ). Additionally, this function decrypts the password
  • SetUserInformation: As opposite to the previous function, this one receives the information fields as parameters and returns a string in the format required to store the information in the database. It also encrypts the password

Forgot password window

logintutorial_45

  • ButtonForgetPWD.Click: Shows the Forgot Password window using the PushScreen function explained in the post  An ‘optimal’ way to manage multiple screens
  • ButtonOk_SEND.Click: Queries TinyWebDB to obtain the information about the username from the database
  • TinyWebDB_SEND.GotValue: Stores the information read into some hidden fields and calls the sendMail function. Finally closes the window using the PopScreen function
  • sendMail: This is the function that performs the actual job. It’s explained in the post How to send direct mails

Menu window

logintutorial_46

  • Button_1.Click, Button_2.Click, Button_3.Click, Button_4.Click: Open the second window passing as a parameter the logged user. It also changes the button to a somewhat lighter color
  • ButtonProfile.Click: Opens the Register window initializing previously the username textbox and disabling it. It also queries TinyWebDB to obtain the information about the username
  • TinyWebDB_Profile.GotValue: Calls the GetUserInformation function in order to convert the information read into a list, and then initializes the fields with this information.