Password security in Nextion HMI

Part 2: A modular software concept

Two weeks ago, we discussed a few password security strategies. If you haven’t already, please read that before continuing. While all the basic mechanisms have been explained and code examples have been shown, using these in your own project might seem difficult since there are so many places where code snippets were to add.

Thinking about that latter aspect and how to ease the re-utilization, I suddenly had an inspiration: Why not follow the example of the keyboard system pages which are automatically added to your project when you link a text or number component to one of the built-in keyboard screens?

The idea is appealing: Put all the required stuff, code, variables, and components into a single page, optimize, test, and debug everything, then lock it without a password just to protect it against accidental changes, and export it. Now, you can add all the functionality to a different project just by importing that page. No more hassle with repeated declaring global variables in the program.s tab and so on… As we’ll see below, this works also (almost) with our password security thing. Why only almost? Because every page which shall be secured with a password requires some code in its Preinitialization and its Exit events. But this can also be simplified by creating a blank page with the required code snippets and exporting it too, once. Then, it can be imported multiple times to any project, as many a you need.

And you’ll even not have to create these pages, you may find the download links at the end of this page.

Another trick to optimize security and memory usage

When you add the secauth page to your project and you unlock it for scientific curiosity, you’ll find there a just 2 x 2 p sized global number component, named a42d77ce, and you might wonder what its purpose is, especially as in the secauth page’s preinitialize event, it is hidden by code:

vis a42d77ce,0

The answer is that it serves as a container to keep the expected CRC16 of the required password or PIN code in its .pco attribute which is by definition a 16bit variable and thus perfectly suited for that purpose. In a similar way, we use its .bco attribute to save the CRC16 of the entered password for comparison. And by the way, since it is already there and accessible, its .val attribute is also used as temporary storage for the length of the entered password. The component’s name has been selected for obfuscation, it looks like a 32bit hexadecimal number while it is a valid component name since it starts with a letter.

Now, with this, we can already show and understand the page preinitialization code of the blank page template. It simply checks if the .pco and .bco attributes of the famous a42d77ce number component are unequal.

If yes, which is the default case after no successful password check happened, it will save the current page id in the global numeric variable loadpageid which is the other global component of the secauth page, so that the latter knows where to go after successful authentication. And then we redirect to the secauth page to ask for a password entry.

If no, which means that a successful authentication has happened and a42d77ce.bco==a42d77ce.pco, the protected page can be loaded.

// Don't modify this code for security concerns
  secauth.loadpageid.val=dp // note curent page for return
  page secauth // if not auth, then redirect else continue
// put your own code below :

Exiting a protected page means simply resetting the authentication result making sure that a42d77ce.bco is something unequal to a42d77ce.pco which is achieved with a bitwise negation:

// Don't modify this code for security concerns
secauth.a42d77ce.bco=secauth.a42d77ce.pco^0xFFFF // reset auth
// put your own code below :

And now, our secauth “module” itself

As seen above, the secauth page interacts with other pages simply through the two global components, a42d77ce and loadpageid. When it becomes the active page, it will show a password entry text component, then a kind of number keys from 0 to 9 for PIN code entry, a “C” key to clear the entry, a “<=Menu” button to return to the menu page without password check, and finally a “Unlock” button to calculate the CRC16 of the entered PIN code and its length and to store it in a42d77ce.bco for further comparison by the protected page, before returning to it with the help of loadpageid where the id of the target page was saved.

All the input keys and buttons are simple text components to save memory and all the event code is centralized in a TouchCap component named proc for easier maintenance:

  pwd_entry.txt+=b[proc.val].txt //append character (0-9)
}else if(
  pwd_entry.txt="" //clear
}else if(
  crcrest 1,0xFFFF  // init crc
  crcputs pwd_entry.txt,0 // append pwd entry
  strlen pwd_entry.txt,a42d77ce.val // calculate pwd length
  crcputs a42d77ce.val,0 // append pwd length
  a42d77ce.bco=crcval // retrieve and save crc
  page loadpageid.val //jump to target page
}else if(
  page menu // jump back to menu page

… and that’s it!

Download your toolbox

Here is the secauth page to be imported once into your project:
(The hard coded PIN code is 145703)

And here the secpage page template to be imported and customized once for every protected page in your project:

Finally, a complete demo project with a menu page, one unprotected, and two protected example pages: crc_pwd_blog_full.HMI

Last but not least…

Don’t forget Nextion’s Back to School promotion: Order Nextion HMI displays and accessories until August 31st, 2022 with the coupon code SCHOOLCOOL and get $10 off on orders >= $59 or even $18 off on orders >= $88. To order, click here!

You are welcome! 😉

Happy Nextioning!