Preparing a Form for Digital Signatures
HTML forms are standard HTML files that contain one pair of <FORM> and </FORM> labels within the body section. In between the form labels one can find several object definitions such as text fields, radio buttons, pull-down menus, and the like. These objects are created with special labels which have a name attribute that defines the variable name that holds the value entered by the user while filling up the form. Usually at the bottom of the page, and before the </form> label, a special object called "submit" is created. This object appears on the page as a Submit button (see CGI Programming with Perl, Second Edition, by Shishir Gundavaram, Scott Guelich, and Gunther Birznieks).
For error checking, or to help the user filling up the form, each input object can define JavaScript functions associated to some events such as OnChange, OnMouseOver, OnClick, and so on. In addition, the form label can also define a JavaScript function that will be called upon submission. In our proposed approach for digital signature, the only JavaScript action necessary is the one defined within the form label.
When the browser loads a web page that contains a form definition, it creates the graphical objects corresponding to the input labels defined in the HTML code, and lets users interact with those objects. Afterwards, when the user hits the Submit button, the browser gathers all the information entered into the input objects and sends variable names and corresponding values to the web server defined in the <FORM> label. If a JavaScript function is called before the data is actually sent, that function may have access to all form variables. A typical JavaScript application is to perform error checking before the data is actually sent to the server. In this article, we show how to generate a digital signature within a JavaScript function called signForm.
To enable digital signature in an existing form, previously created with any HTML editor, just three small changes must be done:
- Add the provided JavaScript code which defines signForm function. This code is added to the head section of the page.
- Add an OnSubmit parameter to the form label to call signForm function upon submission:
<form action="verify.php" method="post" onSubmit="return signForm(this, window);">
- Add two hidden form obejcts to hold the digital signature and the names of the variables in the form:
<p><input type="hidden" name="signature"></p>
<p><input type="hidden" name="varnames"></p>
As you can may see in Figure 2, the text that the user must sign is a list of variable names and values. Consequently, the programmer of the form must use meaningful variable names and meaningful option values. In general, html forms use variable names and values that only make sense to the programmer since those names are not shown to the user (except if an advanced user decides to analyze the source code of the page).
How signForm Works
This function gathers data contained in form input objects, then generates a digital signature by calling crypto.signText. The function signText is part of the JavaScript language included in some browsers like Mozilla/Firefox and Netscape (though not in the current version of Internet Explorer). Until signText function becomes supported by IE, a workaround is to write a JavaScript function that calls CryptoAPI library, which can be made available to IE through Capicom ActiveX control (see Introducing CAPICOM, by John Lambert).
To make signForm useful for any HTML form, regardless of the amount of variables and the specific names of those variables, an algorithm to find all objects in the form was implemented (see Listing One). The number of objects in the form can be found in theForm.elements.length. Then a for loop is used to access each element using the statement elem = theForm.elements[i];.
The main properties of each element are:
- the type of object (elem.type)
- the variable name (elem.name)
- the value entered by the user (value extraction depends on the type of object).
Within the for loop, two string variables are built -- one to store the text to be signed (texttbs) and another one to store the variable names in the precise order in which they have been found in the form (vars). The variable texttbs is built appending the name of each form variable, the character "=", and the corresponding value.
At the end of the loop, the text to be signed is sent to signText function that shows the signing dialog (Figure 2). The result of signText is a digital signature in PKCS#7 format (see PKCS #7: Cryptographic Message Syntax Standard) that is stored in signature variable.
Finally, the signature is copied to the hidden element of the form called signature, and the vars string is copied to the hidden element called varnames. These hidden objects are treated like any other form object, so their variable names, as well as their values, are sent to the server along with all other objects in the form.
It is important to point out that the text to be signed is not sent to the server, since the server must build it again to avoid unencumbered tricks by data misrepresentation, as it will be explained in the following section.
Some input objects (such as the pull down menu) may show a text to the user other than the value stored in the variable of the object. For example:
<option value="spain">Spain (Espaqa)</option>
Both strings can be extracted from the element within the JavaScript function:
elem.options[elem.selectedIndex].value; //extracts "spain" elem.options[elem.selectedIndex].text; //extracts "Spain (Espaqa)"
Although the text label may be easier to understand by the user while signing, the value property is the information sent to the server at submission. Hence, it is more appropriate to work with the value instead of the text label, and accordingly the programmer must use meaningful values instead of values such as 01, 02, 03...