JavaWeb-based JavaProblems with Digital Signing of Documents in Web-based Systems

Problems with Digital Signing of Documents in Web-based Systems

Developer.com content and product recommendations are editorially independent. We may make money when you click on links to our partners. Learn More.

Let’s imagine we are developing an information system with Web-based user interface, which is accessible through the Internet. Users of this system must be able to send documents to the server. These documents can be files of various formats – MS Word .DOC files, Adobe Acrobat .PDF files, MS Excel .XLS files, JPEG and GIF images, text files, etc. In order to track the sender identity and to guarantee nobody modifies documents after their sending, it is necessary that the system can offer users the ability to digitally sign the files being sent. Let us discuss the problems that arise at the implementation of such a system.

The Public Key Cryptography Approach

For the needs of digital signature the system can use Public Key Cryptography, and for verifying the identity of the user who is signing the document, it is most convenient to use digital certificates.

Using Self-Signed Certificates

Certificates can be self-signed or issued by a certification authority. If users issue themselves self-signed certificates and use them to sign documents, there is no guarantee that a malicious user will not issue himself a certificate with another name and sign documents as though he is some other user. We should find better approach to avoid this security weakness.

Using Local Certification Authority

It is possible that the person responsible for the system maintenance – the system administrator – be the one to issue digital certificates. There are two ways to do that – either the system administrator generates the public and private keys for the users, or they generate these themselves. In the first case it is potentially possible for the administrator to abuse his rights. There remains the possibility that the users personally generate their public and private key, afterwards they send somehow the public key along with information about their identity to the system administrator, who in turn issues the certificate. The fault of this design is that it in no way guarantees that users would not fake their identity information. The only possibility left is that every user personally presents his public key and the administrator issues him the certificate after careful examination of his ID papers. This solution is more acceptable, but in fact the administrator acts as a certification authority and is still able to abuse his certificate issuing rights.

Using Approved Certification Authorities

We can use the services of approved certification authorities in order to manage the problems with the certificates. Every user in the system can purchase a certificate from a certification authority and this authority can guarantee that the certificate does really belong to the person it has been issued to. The private key corresponding to any certificate is only accessible to its owner and nobody else. This guarantees that when a user signs a document with a certificate, issued by an approved certification authority, this is really his signature. Faking is only possible if malicious persons obtain the user’s private key, for which the user bears personal responsibility.

Digital certificate purchase involves certain expense for every user, but this is the only reliable way to guarantee security. Usually along with the certificate the user obtains a PFX file, containing the certificate and its corresponding private key, protected by a password. If as a result of the purchase the certification authority installs the certificate directly into the client’s Web-browser, the user is then able to export it as a PFX file (in PKCS#12 format) and use the file from that moment on to sign documents. We assume that users that have their own certificate have also protected keystore (PFX file) that keeps their private key along with their certificate.

Signing Is Possible on the Client’s Machine Only

Signing requires access to the signing user’s private key. Because each user’s private key is accessible only by him, it is necessary that the signing take place physically on his PC. Otherwise the user would have to send his private key to the server, which poses a potential security threat – the key could be stolen on the way. Signing documents on the user’s PC in Web-applications is not an easy task, because the client has only a standard Web-browser at his disposal – which does not have built-in functions for signing documents.

Approaches to Digitally Signing on the Client’s Machine

We will analyze the possible approaches for signing documents on the client’s PC. We should take into account that the signing process should be integrated with the Web-application that is responsible for receiving signed documents.

Using External Signing Tool

A possible approach would be to make users install on their PCs some kind of specially designed software, but this is accompanied by certain difficulties. One is that the signing software must have separate versions supporting different operating systems that users might have. Moreover, support for such software is cumbersome, because any change in it would force users to download and install the new version. Integration with the Web-interface of the system is another difficult task, and if the software is not well integrated, its usage may be troublesome for users. There is also a possibility that users deny to install the software on their PCs because of security reasons, also if they are not using their own machines they may be physically prevented to do it.

The above considerations lead us to looking for another solution of the problem with digital signing on the client machine.

Using Client-Side Scripting Technologies

It is possible to use JavaScript or some other client-side scripting technology, such as ActiveX, Macromedia Flash, .NET Windows Forms Controls or Java-applets.

The problem with JavaScript language is that it does not support the standard functionality required for working with digital signatures and certificates. Besides it is unable to gain access to neither the certificates installed into the user’s Web-browser, nor to external protected keystores. Also JavaScript can not access to local file system and thus can not read the file that should be signed.

Macromedia Flash technology also does not support digital signatures and certificates, and it cannot access local file system, which is required, because before being signed, a file needs to be read.

Technically ActiveX controls offer a solution, but they work only with Internet Explorer on Microsoft Windows. As exception some other browsers in addition to IE also support ActiveX controls, but ActiveX technology can not run on non-Microsoft operating systems. This limits the users to those that use MS Windows and Internet Explorer.

Windows Forms Controls also work only with Internet Explorer, and they additionally require that the Microsoft .NET Framework is installed. It is not acceptable to require the user to use Internet Explorer, MS Windows and .NET Framework in order to be able sign documents in Web-application.

There is one last chance – to use Java applets. They have the advantage that they work with all well-known browsers and on all operating systems. They have the disadvantage that generally have no access to the local file system of the machine they’re running at, but this restriction can be overcome by using signed Java applets. Let us examine what Java applets can offer.

Java Applets

Java applets are compiled Java programs that are embedded as objects in HTML documents and are executed by the Web-browser when the document is viewed. The embedding of an applet in a Web-page is very much like embedding pictures, but unlike them applets are not just graphical images. They are programs that use for their graphical user interface a rectangular area of the page they are set in.

Applets consist of one (or several) compiled Java classes, saved in a JAR file. Like all Java programs, applets are executed by the Java Virtual Machine (JVM) and therefore all Java-enabled Web-browsers have the virtual machine either built-in, or additionally installed. When an HTML document containing an applet is opened, the browser loads its virtual machine and starts the applet in it. To ensure users security, applets are disallowed to execute any operations that might gain access to user information on the machine running the applet. As a rule an applet has no access to the local file system, which makes using this technology for the goals of digital signing somewhat difficult.

Signed Java Applets

Signed Java Applets present a mechanism for increasing regular applets permissions. Like all other applets they represent JAR archives, which contain a set of compiled Java classes, but in addition to that they also contain digital signatures of all these classes as well as a digital certificate (along with its complete certification chain), by which these signatures can be verified. Upon execution of a signed applet the Web-browser displays the information from the certificate used for signing the applet, and asks the user whether he or she trusts this certificate or not. If the user trusts it, the applet executes without any rights restrictions and is free to have full access to the local file system of the machine it is running on. Trusting applets that are signed by an unknown software vendor, or are signed with a certificate that cannot be verified, is highly risky, because these applets gain unrestricted access to the machine and can execute all kinds of malicious code, for example viruses or trojans.

Let’s step forward to the particular problems that occur when writing a Java-applet for digitally signing documents.

Signing Java Applets with jarsigner

In order to access the local file system the applet must be signed. Suppose we have written the applet’s code and we have compiled it to the file Applet.jar. It is necessary to sign this JAR file. For this purpose we can use the utility jarsigner that is distributed standartly with the JDK 1.4. Here is an example:

jarsigner -storetype pkcs12 -keystore keystore.pfx -storepass store_password -keypass
private_key_password Applet.jar signFilesAlias

This command signs the JAR file Applet.jar with the private key, saved in the protected keystore keystore.pfx with the name signFilesAlias, using the passwords store_password and private_key_password to access the keystore and the private key respectively. The jarsigner utility supports two types of protected storage for keys and certificates (keystores) – Java Key Store (.JKS) and PKCS#12 (.PFX files). In order to use it we must either have a certificate issued by a certification authority (PFX file containing the certificate and its correspondinig private key) or we must generate our own self-signed certificate.

Generating Self-Signed Certificates

We can generate our own self-signed certificate with the utility keytool, which is also by standard distributed with the JDK 1.4. Here is an example:

keytool -genkey -alias signFiles -keystore SignApplet.jks -keypass !secret -dname "CN=My Company"
-storepass !secret

This command generates a X.509 certificate and a corresponding private key and saves them under the name signFiles in the keystore SignApplet.jks. In the certificate its owner is written as “My Company”, and to control access to the keystore and private key the password “!secret” is used. By default the keytool utility uses the storage format JKS (Java Key Store).

Furthermore, we can use the thus made certificate to sign our applet like so:

jarsigner -keystore SignApplet.jks -storepass !secret -keypass !secret Applet.jar signFiles

This command signs the applet Applet.jar with the private key that is saved under the name “signFiles” in the keystore SignApplet.jks using for access the password “!secret”. As a result we get a signed JAR file that contains all the files form the Applet.jar archive, together with the digital signatures of these files, and the certificate from the keystore SignApplet.jks with its full certification chain. If no file name is given to write the output file to, as is shown in the example, the input JAR file is also used for the output JAR file.

Embedding Applets in HTML Documents

The code we use to embed a signed applet in a HTML document is by no means different from HTML code we would use to embed a regular applet. Nevertheless when using signed applets it is not recommended to use the obsolete tag <applet>, because it has no way to indicate the minimum JDK version that is required for the proper functioning if the applet. Some Web-browsers (for example Internet Explorer) have standard support for JDK version 1.1 and unless explicitly stated that the signed applet requires a higher version of the virtual machine, the applet is started with restricted rights (as normal non-signed applet) and as a result does not work as intended, or does not start at all. To avoid this it is recommended that the <object> tag is used in Internet Explorer or <embed> in the rest browsers, and that the minimum JDK version the applet requires be pointed. A special utility called HtmlConverter.exe can be used for automatic tag conversion from <applet> to the newer, JDK 1.4 applet embedding tags.

The environment that executes applets in the client’s Web-browser (generally this is Java Plug-In) is responsible for determining whether given applet is signed or not. If it is, upon its loading a dialog is shown that warns that a signed applet, requiring full access to the client system for proper functioning, is loaded. The environment provides detailed information about the certificate the applet is signed with, announces whether it is valid, afterwards it asks the user should it execute the applet without any security restrictions. If the user consents, applet starts with full access rights, otherwise it executes as a regular, non-signed applet.

Accessing the Web Server from Applets

Let us now think upon another problem. The document-signing applet must have some means, by which to send the server the calculated digital signature. This can be realized in several ways – the applet opens a socket to the server and uses this socket to send the signature, or it sends the information by an access request to a server URL, or it communicates with the Web-browser and sends the information to it, which in turns resends it to the server. The last approach is the most convenient, because it requires the least programming efforts in order to send and receive a signed file. In this case the server can receive the file along with its signature in one single Web-browser request, with no need for any other actions.

Communication between Applets and Web Browser

Suppose we have an ordinary HTML form that is used to send files to a certain Web-application without signing them. If we want to expand this form so that it supports digital signing of documents, we can simply integrate a Java-applet for file signing in it. In case we have an applet that calculates digital signature of a file and writes this signature in some field of the HTML form, the efforts for sending the digital signature are minimal. When submitting the HTML form, the Web-browser will send the signature with it, so there is no need for the applet to establish any client-server communication.

Accessing HTML Form’s Fields from Applets

Usually Java-applets can access the code of the HTML they are embedded into. This ability can be used to get from the HTML form the name of the file the user is sending, so that its content can be read and signed. The result from the signing can be returned in some field of the same HMTL form. Technically such interoperability between applet and Web-browser can be realized with the standard class netscape.javascript.JSObject, which is accessible by all browsers that support applet execution. This class offers functionality for accessing all properties in the current Web-browser window the applet has been loaded from, which effectively means we gain access to the HTML document in this window, to the HTML forms in it, to the fields in these forms and in short everything we can access with JavaScript. Some browsers allow applets to run JavaScript and access the HTML document they are loaded from only after explicit declaration in the tag, used to embed them in the page. Such are the “mayscript” and “scriptable” parameters, and they must have value “true”.

Accessing Applet Methods from JavaScript

Generally there is one more way to carry out communication between the applet and the browser – instead of having the applet write the result of the digital signature calculation of the file to be sent in a form field, we could have a JavaScript function call a method of the applet, which returns the signature and again with JavaScript save it in a field of the form. This doesn’t actually work because in most browsers JavaScript is run with rights that do not permit access to the file system. Regardless that the applet is signed and has the permission to read local files if it is invoked through JavaScript it loses this ability. That is why instead of calling a Java function for document signing from JavaScript we can make a button-shaped applet that upon clicking signs the selected file and writes the signature in a predefined field in the form. Optionally we could make the applet through JavaScript to automatically submit the HTML form after signature calculation, so that the user is unable to change the form after the signing is done. In that case it might be convenient to have HTML form without a submit button and submitting the form to be possible only from inside the applet and only if the signing is successful. That way the user will not be able to send unsigned or wrong signed files.

The Process of Signing Documents in the Web-browser

In the process of signing it is necessary that the server is sent not only the document and the digital signature calculated from it, but also the certificate that is being used, accompanied by its full certification chain (if available). The certificate is needed because it stores the signing user’s public key, without which verification is impossible. Besides the certificate provides means to link this public key to the particular person that does the signing. If we send the server only the document, signature and public key, we are able to verify the signature’s validity, but we have no information about the identity of the owner of the public key, unless the server keeps a record of the public keys of all possible clients. In general it is most convenient to send the server the user’s certificate along with its complete certification chain. The particular process that begins with the clicking of the signing applet’s button might be done like this:

  1. The user is prompted to select from the local file system a protected keystore file (PFX file), containing his digital certificate with its corresponding certification chain and private key. The user is required to enter his password to access the information in the selected keystore.
  2. The selected PFX file is loaded and the user’s certificate, corresponding private key and the complete certification chain are extracted.
  3. The name of the file to be signed is taken out from the HTML form. The file is signed with the user’s private key.
  4. The result from the signing together with the user’s certificate and its full certification chain are written to certain fields in the HTML form.

The server that receives the signed file is responsible for checking if the file is correctly signed with the private key, corresponding to the received certificate. Apart from that the server must verify whether the certificate that is used is valid. This can take place immediately after file receipt, or later, if ascertaining the identity of the signer is necessary.

Verifying Signatures, Certificates and Certification Chains

Besides the applet that signs the files sent by the user our Web-based information system should also have functionality for receiving the signed files, together with verification of the signature. It is also necessary that the received user certificates and certification chains be verified in order to make clear who in fact is signing the files. Let’s discuss the problems these verifications involve.

Verifying Digital Signatures

The purpose of digital signature verification is to determine whether the sent signature corresponds to the sent file and certificate, i.e. whether it is authentic. The verification takes place through the standard signature verification procedure – the sender’s public key is extracted from the certificate and a check is made whether the received document’s signature is obtained from the private key corresponding to this public key. There are standard classes in the Java Cryptography Architecture for digital signatures verification.

Verifying Digital Certificates

The verification of the received certificate seeks to determine if the public key stored in it is really owned by the person the certificate is issued to, that is if the user is really the one he pretends he is when he signs the document. This verification is slightly complicated and requires some preparation.

There are several mechanisms to verify a digital certificate. We will examine two of them. The classical way for certificate verification requires that the certification chain be checked. In order to verify a certification chain it is needed all the certificates that it consists of are available. Otherwise verification cannot be done.

In our system during the signing process the user utilizes standard protected storage for keys and certificates (keystore), saved in PFX files. As we already know these files usually contain a certificate and its corresponding private key. In most cases the certificate is accompanied by its full certification chain, but sometimes this chain is not available. For example when the user signs documents with a self-signed certificate, it does not have a certification chain. Therefore it is possible along with a signed file the server receives the user’s certificate with a full certification chain as well as it possible to receive a certificate without a certification chain.

Verifying Certificates with Certification Chains

If a certification chain is present, it can be verified the classical way – by verification of all the certificates (and validity of the links between them) that form the chain. For this purpose Java Certification Path API can be used, and the PKIX algorithm, which is implemented in JDK 1.4. It is only necessary that the application has appropriate set of Root-certificates of trusted top-level certification authorities (trusted CA root-certificates).

Verifying Certificates without Certification Chains

In case the certification chain of the certificate used for signing is unavailable, there is another, although somewhat inconvenient, method for verification – direct certificate verification. Instead of building and verifying the certification chain of a given certificate, it is possible only to verify whether it is directly signed by a trusted certificate. The system can store a list of such trusted certificates. When verification of a given certificate occurs, it can search through the list for a certificate that appears to be a direct issuer of this one. If such a trusted certificate is found, the certificate being verified is considered valid, unless it has expired.

The major inconvenience of this certificate verification scheme is that the system needs to have at its disposal the certificates of all certification authorities that people might use. If for a given user certificate the system does not have the certificate used by the certification authority for signing it upon issuing, this user certificate will not be verified, even though it is valid. Anyway this method for verification may prove useful when users present certificates that are not accompanied by a certification chain.

Note that usually user certificates are not signed directly by the root-certificates of the certification authorities but with some intermediate certificates, signed by some root-certificate of some CA. If we use direct certificate verification, we should have a list of all possible trusted intermediate certificates that are used for direct issuing of the certificates of our clients. The certificates in this list should be certificates that we believe to unconditionally. If we use certificate verification based on certification chains, we need only a list of the root-certificates of the top-level certification authorities we trust and we don’t need the intermediate ones.

Implementing Digital Document Signing System for Web Applications

We have discussed the major problems concerning digitally signing of documents in Web-applications and have proposed particular ideas for their solving through the use of a signed Java-applet. We have also analyzed the problems concerning the verification of digital signatures, certificates and certification chains. Next we are going to examine a system, where concrete solutions to the aforementioned issues have been applied. Let’s move at the most interesting part – the practical implementation of the system.

The next article in this series proposes the NakovDocumentSigner system to give the developers a fully functional framework for digitally signing documents in the client’s Web browsers and verifying signatures, certificates, and certification chains on the server side. The system consists of a Java applet for digitally signing and a reference J2EE Web application for signatures and certificates verification. It demonstrates how the Java Cryptography Architecture and Java Certification Path API can be applied to provide the Web applications with digital signature functionality. The full source code of the framework will be included and discussed.

About the Author

Svetlin Nakov is part-time computer science lecturer in Sofia University, Bulgaria. He has over 5 years of professional software engineering and training experience and currently works as IT consultant in a leading Bulgarian software company. His areas of expertise include Java and related technologies, .NET Framework, network security, data structures and algorithms, and programming code quality. More information on his research background, skills and work experience is available from his home site
www.nakov.com.

Get the Free Newsletter!

Subscribe to Developer Insider for top news, trends & analysis

Latest Posts

Related Stories