Discover the most essential problems connected with the digitally signing of documents in Web-based systems and a particular solution for them.
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
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 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"
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
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:
- 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.
- The selected PFX file is loaded and the user's certificate, corresponding private key and the complete certification chain are extracted.
- 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.
- 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