Better Key Storage With Blackbox, RSA, Redis, and the Fernet Algorithm in Django


Python lacks a proper key store.  This is an unnerving issue when trying to build a secure application. More troubling is the plain text storage of RSA keys. This article examines a process for storing keys in an encrypted manner on black box as well as the storage of keys using the Fernet algorithm and encryption through RSA in Django using redis for speed.


Unlike Java which already has a key store, Python lacks the ability to store keys for data encryption. Python developers are left with only basic methods for storing keys and this often means doing so in plain text.

That method is inexplicably terrible when working with FERPA/HIPPA and especially the increasingly difficult state guidelines for storing sensitive information.


One solution, of many, is to use Stack Exchange black box to store keys and the Fernet algorithm to encrypt the keys in a cache. In this way keys are stored in an encrypted format in a hidden file as well as in a secure format in memory.

Black Box

Stack Exchange’s Black Box offers a perfect storage solution for keys using a gpg keyring to encrypt data. The tool was made to store secrets in a git repository.

Check out my Python API for reading files from black box. It is possible to add a user to the administrator file in order to avoid entering a password each time.

Storing Encrypted Keys in Django

Once the keys are encrypted and accessible, a large application needs to ensure speed. To help alleviate sluggishness, it is possible to store keys using the Fernet algorithm in any cache that Django provides.

It is possible to use the cryptography package for this task.

from cryptography.fernet import Fernet
from django.core.cache import cache

key = Fernet.generate_key()
f = Fernet(key)
token = f.encrypt(b"my deep dark secret")
cache.set('my_token', token)


It is possible to recreate a secure keystore using a mix of Stack Exchange Black Box and the Fernet algorithm when creating a Django application. The implementation above may not be production ready but is a proof of concept.

Encrypting Data in Django with the Fernet Algorithm


At some point, it will be necessary to encrypt data. While most queries are performed raw, there is still a use for the models Django provides in encrypting and decrypting data or even just in obtaining a model from a raw query.

This article examines how to apply the Fernet algorithm to save data in an encrypted format using Django.


Fernet Encryption

Fernet encryption utilizes the AES method at its core. This method is widely accepted and more powerful than RSA when there is no need for communication.

RSA is a powerful tool when requiring that data be passed over the wire. In this example, we are more concerned with data storage.

Secret Key

The Fernet algorithm requires using a secret key to store data.

from cryptography.fernet import Fernet


This key should be stored in a secure fashion. Options for retrieving the key include loading the key from a file passed through an environment variable.

Encrypted Field

Django provides an excellent tutorial for writing custom fields. By overwriting the from_db_value and get_db_prep_value methods it is possible to achieve decryption and encryption respectively.

HOME = str(Path.home())

class EncryptedFernetField(models.TextField):
    A field where data is encrypted using the Fernet Algorithm

    description = "An encrypted field for storing information using Fernet Encryption"

    def __init__(self, *args, **kwargs):
        self.__key_path = os.environ.get('FERNET_KEY', None)
        if self.__key_path is None:
            self.__key_dir = os.environ.get('field_key_dir', None)
            if self.__key_dir is None:
                self.__key_dir = os.path.sep.join([HOME, 'field_keys'])
                if os.path.exists(self.__key_dir) is False:
            key = Fernet.generate_key()
            with open(os.path.sep.join([self.__key_dir, 'fernet.key']), 'w') as fp:
            self.__key_path = os.path.sep.join([self.__key_dir, 'fernet.key'])
        super().__init__(*args, **kwargs)

    def deconstruct(self):
        name, path, args, kwargs = super().deconstruct()
        return name, path, args, kwargs

    def from_db_value(self, value, expression, connection):
        if self.__key_path and value:
            value = base64.b64decode(value)
            with open(self.__key_path, 'r') as fp:
                key =
            f = Fernet(key)
            value = f.decrypt(value)
        return value

    def to_python(self, value):
        return value

    def get_db_prep_value(self, value, connection, prepared=False):
        if value:
            if self.__key_path:
                with open(self.__key_path, 'r') as fp:
                    key =
                f = Fernet(key)
                value = f.encrypt(value.encode())
                value = base64.b64encode(value).decode('utf-8')
        return value

Encrypted values are stored in base 64 to avoid potential byte related issues. This class utilizes the models.TextField to save data as a blob.

Using the Field

The field is used in the same way as any other.

class License(models.Model):
    username = models.CharField(max_length=1024)
    application = models.CharField(max_length=1024)
    unique_id = models.IntegerField(unique=True)
    license = EncryptedFernetField()
    active = models.BooleanField(default=False)
    expiration_date = models.DateField()

    class Meta:
        unique_together = (('username', 'application'), )



Data encryption is fairly straightforward in Django. This tutorial examined how to create an encrypted field using the Fernet algorithm.

WebFlow Designer: Mediocre at Best


Web Flow is one of several visual HTML editors to come on the market in the hopes of replacing Komodo or Dream Weaver. While promising, it may be best to wait for Framer X before purchasing a visual editor.

Since the creation of Wix and the corresponding Wix editor, the idea of giving designers a no-code way to develop web pages has taken root in the development community. The reason such tools have not gained much in the way of popularity is easily apparent with Web Flow.

To be certain, Web Flow contains quite a bit of promise as both a design tool and CMS for simpler websites. The live content editors in particular are a nice to have for teams of any size.

The pros of Web Flow can be summed up as follows:

  • simple, fast, and live development for simple websites
  • basic editing support
  • basic script and style support through an embed tag
  • can be cheaper than a tool such as Dream Weaver for smaller organizations
  • can connect to article-style and other forms of data not requiring heavy back-end support

Just from the pros, it is obvious that a visual editor is perfect for the rapid prototyping associated with the design sprint concept. This is also not a difficult tool to create when considering the current power of Javascript and JQuery, especially when supporting a Mozilla based browser.

For each of the positive characteristics of Web Flow, there is at least one downside:

  • only allows style and script editing in an embed tag
  • contains almost no support for external CSS files
  • cannot be installed on site and does not use a company database
  • fails to provide advanced CSS features beyond a box shadow or border radius
  • class editing cannot be done separately from the generation of an element
  • a parent element must first be created to generate a new class
  • promotes sloppy, terrifying CSS that a middle-ware developer will quit over
  • is not drag and drop and has almost no such support in the editor

Basically, Web Flow and even tools such as Framer area far from ready for the production of modern websites.  Still, if you need to give a designer access to any form of tool that allows for inheritance based web editing or need slightly more than Wikipedia or Wix, Web Flow is decent. Still, Framer X promises to be a much better tool.

This tool, in the current form, is at best a 5/10. It is an average effort from what I hope is not an arrogant fool as can be the case with people who don’t want to actually work on their product that I at least hope will continue to improve to an 8 or 9 of 10.




Fixing Floating Parent Divs

It is frustrating  to float a child element only to find that every element appears to take the same positioning or find the child spilling beyond the borders of the parent. This brief article presents a modern solution to this issue using the display attribute in CSS.


At times when using the float attribute, elements placed in siblings  to a parent tag or even the siblings appear to inherit the floating properties of the target element. Elements may also appear to expand beyond the boundaries of a parent tag.

There are a few root causes of an element causing the parent’s siblings to appear to float including:

  • the zero height problem where an element is larger than its parent
  • the width of an ancestor is specified and violated by the child element


An older solution to the issue is to use the clear fix hack. However, with modern browsers, the solution is simpler:

    display: flow-root;

Specifying flow-root causes the block format to be followed for the elements in the parent. This will maintain the float property of the children and cause the parent to ‘fit’ the child elements.

Using :before or :after in CSS, adding a border to a clipped path

Clip path is great but there is an issue. The border property stops working. Triangles, polygons, and nearly any shape can easily be produced. However, the borders are cut.

This short article examines how to resolve this problem with pseudo images, introducing before and after.


CSS renders the clip path last no matter how it is placed in a CSS class or in what order classes are arranged. This means that margins, borders, and other features are lost when the object is clipped.

Before and After

The solution to the issue is to use CSS to superimpose one div element on another through the use of a pseudo image. Pseudo images can be created using :before or using a standard class followed by :after.

Before and after render content as expected:

        content: '';
        width: 378px;
        height: 178px;
        display: block;
        position: absolute;
        background: #f9fafc;
        top: 1px;
        left: 1px;
                 0% 0%,
                 100% 0%,
                 100% 100%,
                 7.5% 100%,
                 0% 87%);
                 0% 0%,
                 100% 0%,
                 100% 100%,
                 7.5% 100%,
                 0% 87%)
                 0% 0%,
                 100% 0%,
                 100% 100%,
                 7.5% 100%,
                 0% 87%)
        z-index: 1;

       position: absolute;
       width: 380px;
       height: 180px;
       background: grey;
                 0% 0%,
                 100% 0%,
                 100% 100%,
                 7.5% 100%,
                 0% 87%);
                 0% 0%,
                 100% 0%,
                 100% 100%,
                 7.5% 100%,
                 0% 87%)
                 0% 0%,
                 100% 0%,
                 100% 100%,
                 7.5% 100%,
                 0% 87%)
       z-index: -1;

This class clips a div element to create a tab missing the bottom right corner. Two tabs are generated, one positions a single pixel off of the other to create a border. Before must include the gradient and content should be provided.


Before and after are useful tools for placing content and alleviating the problems with clip path.

Differences in Tablets and Browsers Over the Last Few Generations

We all have to do this at some point, create an all encompassing, GUI program that works between the different generations of IPad and even up to 1920 x insane. Increasingly, as of 2018, it doesn’t seem to matter whether you are working in the back or front end, at some point you are creating some sort of front end. Making matters more complicated, a slew of useful and enticing features are starting to become available.

This article is geared towards examining the increasing scale of screen widths in tablets and the differences in available features over time.


Browser features have increasingly grown more powerful. Just a few newer features are:

The links above lead to the MDN pages including browser support. In general, Microsoft Edge or Explorer nearly never supports modern features. However, Microsoft’s browser usage is dropping steadily with Edge taking less than 3 percent of the market and Explorer taking less than 10 percent.

Solid, responsive web applications can be built for Opera, Safari, Chrome, and Firefox without entirely alienating all users but with a slightly outmoded design using CSS hacks or even web frameworks through header parsing.

Firefox, Chrome, and Safari continue to lead the pack in terms of support for newer features.

Device Usage

In terms of devices, the variety of tablet brands is growing. This is leading to a growth in the use of Android devices. This will mean that browsers such as Chrome and Firefox will grow increasingly popular.

Apple continues to lose market share while Microsoft is gaining ground. This could be due to the poor practices of Apple in relation to copyrights and development.

Reactive Trend

The overall trend is towards responsive web development. Each page scales to nearly any resolution required with the exception of mobile which requires a separate site.

This trend carries towards features as well. The days of using stateful web design, jumping from page to page, are nearly dead. Each page is practically a

Future development and certainly my own are also abandoning the typical grid system. Divisions can now become polygons. It is possible to draw complex shapes with d3js.

Web Applications in Unexpected Places

Anything and everything is becoming possible. Web applications are achieving the same power as desktop and mobile applications. However, security will still be a concern.

This power includes on the monitoring side of the IOT sphere. With the ability to launch a browser through tools such as QT and PyQT,  web applications will start showing up in unexpected places.

Consequently, web sockets, RTC, MQPP, and XMPP  will likely grow in popularity.

Screen Sizes

Screens have grown in resolution at the low and high end as expected. Since 2012, screen resolutions have grown from 960 x 720 for an IPAD to 1024 x 768 as well as up to 1366 x 768 on desktop, up from 1280 x 800.

A basic website should be safe coding, in 2018 using:

  • 960 x 720: Older Generation IPads
  • 1024 x 768: Newer Generation of IPads and older desktop screens
  • 1280 x 800: For older screens
  • 1366 x 768: The most common resolution of 2018
  • 1920 x 1080: The future most popular resolution

To stay relevant, plan on coding for both Ipad resolutions as low as 960 x 702 and desktop resolutions as high as 1920 x 1080. My own sites split this resolution into 7 different tiers.

Of course, create a mobile site as well at about 420 width.

The tiers I use are:

  • 900 – 999 width
  • 1000 – 1199 width
  • 12000 – 12299 width (some computers have bizarre resolutions in this range)
  • 1300-1399 width
  • 1400-1599 width
  • 1600 – 1799 width
  • 1800+ width


Frameworks have not changed much but have gotten better. Django now supports channels, Spring has been fully coupled with boot for some time, and Flask is becoming more secure.

More interestingly, React has gained ground due to the power it maintains in building responsive applications. This is really nothing new.

Personally, I utilize Django these days with Flask for micro-services. This allows me to  maintain as single stack for both my front and back-end which utilizes Celery,  Thespian, PyTorch, and Python’s other powerful data tools.