O4W Password Encryption

Overview

The solution:

Upgrading to 1.1

Since O4W systems are already “in the wild” with clear-text passwords stored in the O4WPERMS table, the 1.0→1.1 O4WUpgrade process will:

User Maintenance in O4W

The user maintenance screen has been modified to comply with the ideas above:

O4W Login screen

The O4W Login process has been modified to comply with the ideas above:

Login authorization

The default login authorization routine (O4WI_AUTHORIZE) has been modified to accept _3_ parameters: the username, the hashed value sent by the browser, and the current time value;

O4WI_AUTHORIZE will now:

If the two values match, the user is authorized to proceed;

Developers who specify their own custom authorization routines (via the O4WCONFIG record) will continue to be passed 2 parameters (the username and the UNENCRYPTED password);

Developers who wish to use the encryption routines to make their systems secure, but who still wish to have a custom authorization routine, may do so by creating an authorization routine whose name ends in “ENCRYPT” (ie, “MYCUSTOMPROC_ENCRYPT”). If the authorization routine’s name ends in “ENCRYPT”, O4W’s login process will instruct the browser to encrypt the password, and send that authorization routine the same 3 parameters as O4WI_AUTHORIZE.

New utility function: O4WI_ENCRYPT

The O4WI_ENCRYPT routine takes up to 3 parameters; the first 2 are mandatory, the last one is optional:

FUNCTION O4WI_ENCRYPT(param1, param2 {, param3})

It performs a “hash” on the first two parameters, and then (optionally) hashes that value with the third parameter;

This function is used by the O4WI_AUTHORIZE and O4WUPGRADE routines to generate and validate the hashed value, and could be used by a developer’s custom authorization routine that also used encrypted values;

This function relies on an updated RTI_MD5 to perform an “hmac sha1” hash

New O4WQUALIFYEVENT event: ENCRYPT

The O4WQUALIFYEVENT function has been enhanced to support a new ‘event’, “ENCRYPT”:

O4WQUALIFYEVENT(“<sourceID>”, “ENCRYPT”, “<targetID>”, “<hash_param1>” {, “<hash_param2>”})

<sourceID> and <targetID> are the O4W IDs of the field to encrypt and destination for the hash, respectively;

<hash_param1> is the O4W ID or literal string (enclosed in quotes) to use when hashing the <sourceID>

<hash_param2>, if specified, is the O4W ID or literal string (enclosed in quotes) to use when hashing the hash generated in the previous step

Specifying this event will generate a script that, when the contents of the <sourceID> control have been modified, and the control has “lost focus”, will hash the value stored in the <sourceID> control against the one or two other values, and store the result in the <targetID> control. In addition, it will change the value in the <sourceID> control to a known value, not related to its original value, so that the original entered value is never transmitted to the host

Example:

CASE EVENT _EQC ‘CREATE’

 * … initial code ….

O4WStore(“”, “myHash”, “myHash”) ;* the control where we’ll store the hashed result

O4WPassword(“”, “”, “”, “ourPWD”, “ourPWD”) ;* the control where the user will type in the password

O4WQualifyEvent(‘ourPWD’, ‘ENCRYPT’, ‘myHash’, ‘”b8291af880217262cc82965”’) ;* hash the value that’s been entered into ourPWD against the literal string and put the hashed value into myHash

* … more code …

 CASE EVENT _EQC “CLICK”

pwdHash = O4WGetValue(“myHash”) ;* hashed password value

dummyPwd = O4WGetValue(“ourPWD”) ;* not used - always return “eNcRyPtEd” as the text

* … validation code …

In practice, the <hash_param1> will usually be the “seed” value stored in the DICT O4WPERMS “SALT” record, field 2