by Mahendra Palsule
Just as there are constructors and destructors in an object-oriented language, there are creators and destroyers of software. While software developers invest millions of dollars in creating sophisticated applications, anonymous hackers and authors of software viruses expend their effort in modifying, reverse engineering, and corrupting original software.
The Internet explosion in this decade has turned this key concern of the information technology industry into a pressing issue. While the ubiquitous World Wide Web offers unprecedented capabilities for software developers, its fundamentally insecure framework offers a similar opportunity for those with unscrupulous intentions.
When today's Web surfers browse enhanced Web sites, they often download software either in the form of Java applets and ActiveX controls or as software applications, shareware demos, and so on. Software is also distributed or delivered across the Internet via e-mail attachments or by using File Transfer Protocol (FTP).
To ensure that this software is indeed from a reliable source and has not been tampered with in any way, a security mechanism is required to verify the genuineness and integrity of the code before it is installed and executed on the user's system.
In this chapter you will see how Microsoft's Authenticode technology addresses these concerns using digital signatures and Software Publisher Certificates.
Code-signing technology is used to verify the identity of the
software publisher and check the integrity of the software so
that users can be assured of the trustworthiness of the code.
Code signing involves bundling digital signatures along
with the original code, which remains unchanged.
| NOTE |
From the perspective of verifying the source and integrity of code, understand that the executable code, or software component, is akin to a chunk of data. Hence, in the context of code signing, the software component is frequently referred to as the data that is signed |
Before I explain about Authenticode and the tools used to sign code, a discussion of some key concepts related to code signing is in order. The nuts and bolts of the Authenticode security model are digital signatures and certificates. Although you do not need to delve deep into encryption technology, a clear grasp of the fundamental concepts would go a long way toward using the code-signing tools productively.
A digital signature is a fixed-length piece of binary data that is created as part of the code-signing process. Digital signatures can be used along with software code as well as with any data such as messages or documents. The identity of the signer and the integrity of the data since it was signed can be verified by the receiver of the message or the end user of a software component.
Digital signatures use public-key algorithms that are designed to work with a key pair. A key pair consists of a private key that is used to encrypt the data and a public key that is used to decrypt the encrypted data. The private key is kept confidential by the signer, whereas the public key is made available along with the signed data. The public key is distributed with a certificate, which I will explain in the next section.
Because the original software component may be of a huge size, a fixed-length encrypted digest is first created before using the private key to sign it. The digest is created using a one-way hashing algorithm, which means that the original data can never be retrieved from the digest using the hashing algorithm.
The digest or hash value is like the fingerprint of the original data. The hashing algorithm is sensitive to any discrepancies in the original data at the bit level, so reapplying the hash algorithm to a modified version of the data creates a different digest. The creation of a digital signature is illustrated in Figure 23.1.
Figure 23.1 : The process of creating a digital signature.
Using a signature algorithm and the private key of the signer, the encrypted digest is transformed to create the digital signature that is transmitted along with the original code. The hashing algorithm used to create the digest and the signature algorithm used to sign the digest should be the same at both ends of the code transfer.
The recipient of the signed code uses the hashing algorithm on the code to create a digest. Then, using the digital signature algorithm with the public key of the signer, he decrypts the digest in the accompanying signature. The process of verifying digital signed code is illustrated in Figure 23.2.
Figure 23.2 : The process of verifying a digital signature.
If the two digests are identical, the source and integrity of the code are verified. If there is a mismatch, it indicates that the received code does not match the one originally signed by the signer.
Two common hashing algorithms used are the MD5 Message Digest and the Secure Hash Algorithm (SHA) algorithms.
The MD5 hashing algorithm, which generates a 128-bit hash value, was developed by RSA Data Security, Inc. The SHA was co-developed by the National Institute of Standards and Technology (NIST) and the National Security Agency (NSA).
With the digital-signature technology I've outlined, the public key that is freely distributed may be used by unscrupulous individuals to impersonate others. If a software component allows a user to enter his user ID and public key, for example, an impersonator can substitute his own public key while entering another person's user ID.
Public-key certificates are documents issued and signed by a trusted authority containing someone's user ID and public key. The trusted authority is known as a certification authority (CA). The CA is responsible for verifying the credentials of a user before issuing the certificate. Figure 23.3 shows the certificate for the Microsoft Certificate Enrollment ActiveX Control, issued by VeriSign.
Different entities may take on the role of the CA in different environments. For example, the IT department of a company may be the CA for users of the company's network, and an Internet service provider may act as the CA for its subscribers. The situation in which the recipient does not trust a particular CA is handled by the concept of a trust hierarchy.
A trust hierarchy is similar to how you are more likely to trust a friend's friend rather than a complete stranger. If a complete stranger established a chain of individuals starting from a friend you trust, with each trusting the next in the chain, you would find yourself able to place your trust in that stranger.
Ideally, there would be a root trusted authority whom everybody trusted-perhaps a federal government agency or a trustworthy company. Digital certificates could then be easily created from the linear chain of the trusted authorities leading to the root CA.
How are certificates digitally represented? Public-key certificates are in the industry-standard X.509 format discussed in the following section.
The industry-standard X.509 protocol specification includes a structure for public-key certificates. The X.509 certificate is a cryptographic certificate containing the unique name of the vendor and the public key of the vendor. The certificate is signed by the CA issuing the certificate. The format of the X.509 certificate is shown in Figure 23.4.
Figure 23.4 : The X.509 certificate format.
The Software Publisher Certificate (SPC) is the document issued by the CA that conforms to the industry-standard X.509 certificate with Version 3 extensions. Each digital certificate is linked to the certificate of the CA that signed it, thus forming a linked chain of certificates.
Multiple X.509 certificates are encapsulated in a format defined by the Public Key Cryptography Standard #7 (PKCS#7). Among other things, this standard defines a standard representation of a signature block. The PKCS#7 signature block can contain multiple certificates along with the data that is signed. This signature block is also referred to as a signed-data object.
The SPC is a PKCS#7 signed-data object containing the X.509 certificates of the signer, the root certificate supplied by the CA, and the signer's public key. The signer or software publisher is the subject of the certificate.
This SPC is used to create the final signature file containing a PKCS#7 signed-data object that is distributed along with the code. For code that is downloaded in the portable executable (PE) format, this signature file is stored in the binary file in a separate section.
Now that you have an understanding of the fundamental concepts of code signing, I will now discuss Microsoft's Authenticode code-signing technology.
Authenticode is a security mechanism that puts end users in control of what software is allowed to run on their system. Authenticode is currently implemented in Microsoft Internet Explorer 3.0. All Microsoft development tools will incorporate support for code signing using Authenticode in future releases. I will first present an overview of Authenticode and then discuss its relevance from the perspective of Java developers.
The Authenticode technology implemented in Internet Explorer 3.0 alerts users before downloading and executing software from the Internet. Authenticode currently supports signed Win32 Portable Executable (PE) format files, which may be in the form of Java applets, ActiveX controls, plug-ins, executables, cabinet files, and so on. If the code has been signed by a CA, the certificate is displayed to the user. If the code has not been digitally signed, Internet Explorer by default does not download the code.
The user can set the safety level of this security mechanism to one of three settings by choosing Safety Level from the Security tab in the dialog accessed from the View | Options menu, as shown in Figure 23.5.
Figure 23.5 : Safety-level settings in Internet Explorer 3.0.
With the default security setting of High, Internet Explorer avoids downloading any unsigned code and displays a dialog box to the user noting that a potential security hazard was avoided. With this default setting, users cannot view any Web page that contains unsigned code, thus preventing malicious code from being downloaded to the average user's system.
A Medium security setting warns expert users and developers if Internet Explorer encounters unsigned code, but gives them the option of downloading the unsigned code. A security setting of None assumes all code to be safe and downloads all code whether signed or unsigned.
Users can also configure Authenticode in Internet Explorer using Personal, Site, and Publisher certificate options found in the Security tab of the Options dialog box, as shown in Figure 23.6.
Figure 23.6 : Security options in Internet Explorer 3.0.
The Authenticode code-signing technology can be used by software developers to build a trusted relationship with their customers. The code-signing process ensures that customers always use original software. Using Software Publisher Certificates for code signing builds brand recognition among the developer community.
Code-signed software can also be used by Web sites that host software
libraries and shareware programs on the Internet. If Web sites
host code-signed software, they will have an enhanced reputation
and can ensure that users download authentic code.
| NOTE |
Authenticode does not guarantee that the signed software component is bug free. Also, it cannot be used for software copy protection |
As you have seen, the Authenticode code-signing technology is not restricted to ActiveX components, but also can be used to sign Java .class files and .CAB cabinet files. Because the underlying digital-signature technology is independent of the file format, future Authenticode releases will support documents with embedded macros and Macintosh executables. Microsoft is also exploring possibilities for signing HTML code and entire Web pages.
In the corporate environment, the Internet Explorer Administration Kit allows administrators to preconfigure Internet Explorer security settings and control which settings can be changed by users.
Java uses a security model based on the concept of a trusted computing base, commonly referred to as a sandbox. I'll review the basic properties of the sandbox before looking at how Authenticode works with Java.
Java applets downloaded from the Internet are executed in a restricted environment in the Java Virtual Machine (JVM) on the client system. The JVM considers these downloaded applets as untrusted, in contrast with trusted applets that are loaded from the local file system. The following restrictions apply to untrusted applets:
This restricted environment is likened to a sandbox because it is supposed to be difficult to get out of one. There are two limitations in the sandbox security model, however.
First, the sandbox approach limits the functionality of downloaded Java applets. File-system access and the capability to use libraries and other programs on the client system are essential features of most useful software. Java has yet to deliver much of its promise due to these restricting features of the sandbox security model.
Secondly, the sandbox acts as the sole barrier between possibly hostile code and precious system resources. A single barrier, however impenetrable, is not recommended for today's needs of electronic commerce. Responsibility for security should be distributed.
Sun Microsystems plans to include support for digital signatures, digests, and key management in the next major release of the Java Developer's Kit, version 1.1. Microsoft has taken the initiative in resolving the problem of trusting downloaded code with the Authenticode code-signing technology.
Authenticode can be used in conjunction with the sandbox for overcoming the limitations of the sandbox security model. Authenticode provides the mechanism for accountability that gives the user the freedom to decide whether a Java applet can step out of the sandbox.
Authenticode enables digitally signed Java code to use system resources, perform file I/O, make system calls, and invoke other programs on the client system. Java programs can also use component object model (COM) services of a COM object on the client system.
Internet Explorer 3.0 considers downloaded Java code that is digitally signed with a valid Software Publisher Certificate as trusted and allows it to step out of the sandbox. Unsigned Java applets downloaded from the Internet can still execute within the sandbox supported by Internet Explorer 3.0. Thus Authenticode technology incorporated in Internet Explorer 3.0 enhances the Java sandbox security model and works in conjunction with it.
Now let's look at how you can create signed Java code that can be downloaded and used as trusted code.
The Cab&Sign directory on the Visual J++ CD-ROM contains
the self-extracting file Codesign.exe that contains the
code-signing tools, utilities, and documentation.
| TIP |
You can get the latest version of the toolkit from the Microsoft Web site. The code-signing tools are included as part of the ActiveX Software Development Kit (SDK), which is available for free download at http://www.microsoft.com/activex/ |
The tools are not installed automatically by the Visual J++ setup program. You should copy the self-extracting executables and install them yourself in the directory of your choice. The next sections discuss how to use these tools.
The self-extracting Codesign.exe file installs the programs
listed in Table 23.1.
| Program | Purpose |
| MakeCert | Creates a certificate for testing purposes only |
| Cert2SPC | Creates a test Software Publisher Certificate |
| SignCode | Uses a Software Publisher Certificate to sign code |
| PeSigMgr | Inspects the certificate in a signed file |
| ChkTrust | Checks the validity of a signed file |
All of the programs listed in the table, except for SignCode, are command-line tools. As noted, the MakeCert and Cert2SPC programs are provided for testing purposes only and should not be used after you obtain a valid Software Publisher Certificate from a Certification Authority.
The following sections discuss the use of each program in detail.
As its name suggests, the MakeCert program is used to generate a test certificate. The MakeCert program can generate a public/private key pair and associate it with a name you choose. It creates an X.509 certificate that contains your name bound to the public key in the signature.
You can view the options and their syntax for MakeCert by typing makecert -? or simply makecert at the command prompt. The syntax for using MakeCert is
makecert [options] outputCertificateFile
The various options for MakeCert are shown in Table 23.2.
| Option | Purpose |
| -u:subjectKey | Specifies the publisher's key-pair name. If the key pair does not exist, it will be generated. |
| -U:subjectCertFile | You can use an existing public key in a certificate with this option. Specifies the filename of the certificate to use. |
| -k:subjectKeyFile | Specifies the location of the subject's private-key (.pvk) file. The private-key file contains the publisher's private key. This option can also be used to create the file if it does not exist. |
| -n:name | Specifies the name for the publisher's certificate, conforming to the X.509 standard. |
| -d:displayname | Specifies the name of the publisher that is displayed in the user interface of the certificate. |
| -s:issuerKeyFile | Specifies the location of the issuer's key; defaults to the root key provided for testing purposes. |
| -i:issuerCertFile | Specifies the location of the issuer's certificate. |
| -#:serialNumber | Specifies the serial number of the certificate. Specifying this value is optional; the maximum value is 2 raised to the power of 31. The default value generated is guaranteed to be unique. |
| -l:policyLink | Specifies a hyperlink to SPC Agency policy information that will be created in the certificate. |
| -I | Explicitly specifies that the certificate would be used by individual software publishers. |
| -C | Explicitly specifies that the certificate would be used by commercial software publishers. |
| -C:f | Explicitly specifies that the publisher met the minimal financial criteria of the CA. |
| -S:session | Specifies the session name for the enrollment session. |
| -P:purpose | Specifies why the certificate is to be generated. The possible values are CodeSigning (default) and ClientAuth for client authentication. |
| -x:providerName | Specifies the cryptographic service provider to use. |
| -y:nProviderType | Specifies the cryptographic provider type to use. |
| -K:keyspec | Specifies the key. The possible values are S for a signature key (default) and E for a key-exchange key. |
| -B:dateStart | Specifies the start date of the validity period. The default is when the certificate is generated. |
| -D:nMonths | Specifies the duration of the validity period. |
| -E:dateEnd | Specifies the certificate expiration date. The default value is the year 2039. |
| -h:numChildren | Specifies the maximum number of certificates that can be linked below this certificate in the certificate chain of the trust hierarchy. |
| -t:types | Specifies the type of certificate. Possible values are E for end-entity and C for certification authority. You can use either or both values. |
| -g | This option will not be supported in future versions of makecert and should not be used. |
| -r | Creates a self-signed certificate. |
| -m | Specifies that the MD5 hash algorithm should be used. MD5 is the default algorithm used. |
| -a | Specifies that the SHA1 hash algorithm should be used. |
| -N | Includes the Netscape client-authentication extension in the certificate. |
You do not need to use most of the options to create an X.509 certificate with default values. A typical invocation of MakeCert would be
c:>MakeCert -u:MyUniqueKey -k:MyUniqueKeyFile -n:CN=MyCompany myCert.cer
This generates a certificate file myCert.cer with a signature
in which the public part of the key pair MyUniqueKey
is bound to the publisher MyCompany. If the key pair
MyUniqueKey does not already exist, it is generated along
with the MyUniqueKeyFile file in which the key pair is
stored.
| NOTE |
The myCert.cer certificate just created cannot be used to actually sign code using the CodeSign program. You must use a valid SPC before you begin actually signing your code |
You can create a test Software Publisher Certificate from the certificate created by MakeCert using the Cert2SPC (certificate-to-SPC) program.
This program encapsulates the certificate created with MakeCert and the root certificate into a PKCS#7 signed-data object. It is also possible to include additional certificates into the SPC. The syntax for using Cert2SPC is
Cert2SPC cert1.cer cert2.cer ... certN.cer output.spc
where cert1 ...certN are the names of the certificates to be included in the SPC, and output.spc is the name of the PKCS#7 signed-data object that is created.
A typical invocation of the Cert2SPC program would be
c:>Cert2SPC root.cer myCert.cer myCert.spc
This generates a Software Publisher Certificate myCert.spc
including the root.cer and myCert.cer certificates.
| NOTE |
The Software Publisher Certificate myCert.spc just created is not a valid SPC and cannot be used to actually sign code using the CodeSign program. You need a valid SPC from an appropriate CA to begin signing your code |
SignCode is the actual code-signing program you use to sign your code. Before you begin using SignCode, you must obtain a valid Software Publisher Certificate from a trusted Certification Authority.
You can use SignCode either by specifying options on the command line or by starting SignCode without any parameters to invoke the Code Signing Wizard.
The syntax for using SignCode from the command line is
SignCode -prog ProgramFile -spc Credentials -pvk PrivateKeyFile/KeySet Name -name opusName -info opusInfo -gui -nocerts -provider CryptoProviderName -providerType n [-commercial|-individual] [-sha|-md5]
In this syntax
Here's how you can use SignCode from the command line to sign your Java applet's .class file:
c:>SignCode -prog myApplet.class -spc myCert.spc -pvk MyKey
SignCode does the following in response to the preceding command:
If you like wizards, you can use the Code Signing Wizard by executing SignCode without any parameters. The Code Signing Wizard starts, as shown in Figure 23.7.
Figure 23.7 : The Code Signing Wizard's welcome screen.
Press the Next button to proceed with signing your program. The wizard asks you the program you want to sign, the name you want to give to the signed program, and the location where additional information about your program can be obtained. Figure 23.8 shows the next screen of the wizard after the relevant information has been entered.
Figure 23.8 : The Code Signing Wizard, Step 1: program information.
The information you specify in this step maps to the -prog, -name, and -info command-line parameters.
Clicking the Next button takes you to the next step of the Code Signing Wizard. You need to specify the credentials that would be used to sign the program, the location of the private key with which the program would be signed, and the hashing algorithm you want to use to create the cryptographic digest from your program. Figure 23.9 shows this step of the Code Signing Wizard with the relevant information supplied.
Figure 23.9 : The Code Signing Wizard, Step 2: security information.
The information you specify in this step maps to the -spc, -pvk, and either -sha or -md5 of the SignCode command-line parameters.
Pressing the Next button brings up the Code Signing Wizard's information review screen. (See Figure 23.10.)
Figure 23.10 : The Code Signing Wizard, Step 3: information review.
Observe that the information in the first five fields is what you entered in the previous two steps. The bottom field of the list shows the cryptographic service provider that the Code Signing Wizard uses, which is the Microsoft Cryptographic Base Provider version 1.0 supplied along with the Windows 95 and Windows NT operating systems. The Cryptography API Provider module provides the implementation for encryption, hashing, and signature verification algorithms.
Press Next after you finish reviewing the information, and the Code Signing Wizard comes to the final step in the code-signing process. (See Figure 23.11.)
Figure 23.11 : The Code Signing Wizard, Step 4: signing code.
Click the Sign button to sign your code. If the Code Signing Wizard successfully signed your code, a message box pops up, as shown in Figure 23.12.
Figure 23.12 : The Code Signing Wizard's success message.
You are finished using the code-signing tool. Now you need to verify that your code has indeed been signed correctly.
The PeSigMgr (portable executable signature manager) program can check a portable executable image file to verify that it contains a PKCS#7 signature block. It can also list, add, and remove the certificates from a signed file.
The syntax of PeSigMgr is
PESIGMGR [options] signedFile
where signedFile is your signed program file. The various options are
If you signed the mySoftware.exe file, you can check the existence of the certificate in mySoftware.exe by entering
c:>PeSigMgr -l mySoftware.exe
If a certificate is found in mySoftware.exe, PeSigMgr gives the number, revision, and type of the certificate. A typical output of the PeSigMgr program is
>Certificate 0 Revision 256 Type PKCS#7
Note that PeSigMgr only checks for the existence of a certificate in the signed code. It does not verify the signature in any way. It is only used for checking whether SignCode really signed the program.
To check the validity of a signed software component, you should use the ChkTrust program, which is explained in the following section.
The ChkTrust program is used to check the validity of a signed file. The syntax for ChkTrust is
c:>ChkTrust [-c|-i|-j] signedfile
In this syntax
For example, ChkTrust could be invoked to verify the signed file myApplet.class:
c:>ChkTrust -j myApplet.class
When you invoke ChkTrust like this, it does the following:
A successful response gives the following output:
Result:0
In this section, I have discussed the tools you need to sign your Java applets. There is a better method to embed signed Java code in a Web page, which is discussed in the next section.
Enhanced Java applets are large, use multiple .class files, and typically require a set of image and audio files. Normally, each file required for the applet is downloaded individually. Further, the .class files and the audio and image data are downloaded in uncompressed format. Individually downloading multiple uncompressed files results in longer download times for large applets.
Cabinet (CAB) files can be used to compress multiple files into a single .CAB file. CAB file technology has been used for distributing Microsoft software such as Windows 95. Individual files required by a Java applet can be stored in a single CAB file, resulting in faster download and execution of Java applets.
Signed CAB files are well suited for the distribution of class
libraries. Developers of class libraries can incorporate the complete
directory hierarchy of their classes in the CAB file. The mechanism
for downloading CAB files also provides support for version control
and vendor conflict.
| Note |
Sun Microsystems plans to include Java archive (JAR) file technology in the next major release of the Java Developer's Kit, version 1.1. The features of JAR and CAB files are quite similar |
Along with the Codesign.exe file, there is an accompanying self-extracting executable file CabDevKi.exe in the Cab&Sign directory on the Visual J++ CD-ROM.
The CabDevKi.exe installs the files listed in Table 23.3
to the directory you specify.
| Filename | Purpose |
| diamond.exe | The compression tool to make cabinets |
| cabarc.exe | Alternative, simpler tool for making cabinets |
| classpck.ddf | Template file for including applet files in the CAB file |
| master.ddf | Template files for including Java libraries in the CAB file |
| master.inf | Setup information file for libraries in the CAB file |
| README.txt | Release documentation provided with the cabinet development toolkit |
| overview.htm | Overview of the cabinet file technology |
| outline.gif | Image file used in overview.htm |
| diamond.doc | Overview of the compression used for CAB files |
There are two ways to create CAB files. The simpler method is to use the cabarc utility. There is another method using templates, which involves additional steps in creating CAB files. Here I will discuss the cabarc utility, which is recommended for applet developers.
The syntax for the cabarc utility is
CABARC [<options>] <command> <cabfile> [<filelist...>] [dest_dir]
There are three commands to list and extract files from CABs and create new cabinets:
Here are some sample invocations of these commands:
You can use the following options with these commands:
The two significant uses of these options are support for parsing a directory structure and support for embedding digital signatures in the CAB file.
The simple applet with animation support developed using the Applet Wizard can be a case study for seeing the benefits of CAB file technology. Developing a sample applet with multithreading and animation support using the Applet Wizard creates a single class file and a subdirectory for images. Using cabinet file compression, there is a 30 percent reduction in the number of bytes that need to be downloaded. In situations involving a larger number of class files and other audio and image data, there can be remarkable savings in download time.
The CAB file technology supports the following API calls made by the applet for loading image and audio data:
These are the most common methods used to load images and audio data from the Internet. When an applet from a CAB file calls these APIs, the system first tries to find the requested files in the local CAB file that is already downloaded. If it does not find the necessary files within the CAB file, the system tries to fetch it in the normal way across the Internet.
Applet developers can use the CABBASE parameter of the <APPLET> tag to make use of cabinet files. Internet Explorer versions 3.0 beta 3 and later support the CABBASE parameter. Using the CODEBASE parameter as well ensures that browsers that do not support the CABBASE parameter will also be able to download the code. Thus, here's a sample HTML code using the cabinet file for the Java applet when the .class files are located in a different directory than the HTML page:
<APPLET CODE="myApplet.class" CODEBASE="/java/classes/" WIDTH=m HEIGHT=n> <PARAM NAME="cabbase" VALUE="myApplet.cab"> </APPLET>
You have now seen how you can use cabinet files effectively in conjunction with Authenticode to decrease download times and enhance the performance of Java applets.
The Authenticode code-signing technology is the leading initiative toward software accountability on the Internet. More than 40 companies have endorsed the Authenticode proposal. Companies such as VeriSign and GTE are providing the underlying infrastructure of Trusted Authorities for the digital signature and certificates initiative. Standard policies for issuing digital certificates for individual and commercial software publishers are being framed.
As the code-signing initiative gains momentum, Internet users will be in control of what software is allowed to run on their system. Whether an umbrella organization evolves to ensure standardized policies for Certification Authorities remains to be seen.