The DigestInputStream Class Message Digest Streams

b[1] = byte hash 16; b[2] = byte hash 8; b[3] = byte hash 0; engineReset ; return b; } } The implementation of this class is simple, which isnt surprising given the fact that the algorithm itself is too simple to be considered an effective digest algorithm. The major points to observe are: The name of the class XYZMessageDigest and the name of the algorithm that it implements XYZ must match one of the strings in the provider package for this class to be found. Hence, in our provider class in Chapter 8, we included this property: putMessageDigest.XYZ, XYZMessageDigest; • Our constructor must be public and take no arguments. It must call the superclass constructor passing the name of the message digest algorithm it implements. • In order for the getDigestLength method to function, we chose to implement the Cloneable interface instead of overriding the engine−GetDigestLength method. Since there are no embedded objects in this class, we do not need to override the clone method. The default implementation of that method a shallow copy is sufficient for this class. • The engineUpdate methods accumulate bytes of data until an integer has been accumulated, at which point that integer can be XOR−ed into the saved state held in the hash instance variable. • The engineDigest method converts the hash instance variable into a byte array and returns that to the programmer. Note that the engineDigest method is responsible for resetting the internal state of the algorithm. In addition, the engineDigest method is responsible for padding the data so that it is a multiple of four bytes the size of a Java integer. This type of data padding is a common feature of message digest calculation. • The engineReset method initializes the algorithm to its initial state. • Once we have an implementation of a message digest, we must install it into the security provider architecture. If we use the XYZProvider class from Chapter 8, we can change our Send class above to use our new digest algorithm: package javasec.samples.ch11; import java.io.; import java.security.; import javasec.samples.ch08.XYZProvider; public class SendXYZ { public static void mainString args[] { try { Security.addProvidernew XYZProvider ; FileOutputStream fos = new FileOutputStreamtest.xyz; MessageDigest md = MessageDigest.getInstanceXYZ; ObjectOutputStream oos = new ObjectOutputStreamfos; String data = This have I thought good to deliver thee, + that thou mightst not lose the dues of rejoicing + by being ignorant of what greatness is promised thee.; byte buf[] = data.getBytes ; md.updatebuf; oos.writeObjectdata; oos.writeObjectmd.digest ; } catch Exception e { System.out.printlne; } } } Similar changes to the Receive class will allow us to accept the message that weve saved to the file test.xyz.

11.4.1 The MacSpi Class

Implementing a MAC is similar, except that you extend the MacSpi class javax.crypto.MacSpi . The method names within that class follow the method names of the Mac class: there is an engineDoFinal method instead of an engineDigest method, and so on. The key to the implementation of the engineDoFinal method is that it should use the key it received in the engineInit method to calculate a secure message digest perhaps using the technique we outlined above when we used a simple passphrase. Remember that the Mac class is a JCE engine, so the constructor of your MAC implementation must verify the JCE installation.

11.5 Comparison with Previous Releases

In Java 1.1, there is no MessageDigestSpi class, and the MessageDigest class simply extends Object . If you want to implement your own message digest in 1.1, then you extend the MessageDigest class directly. This does not cause any implementation differences. The getDigestLength method does not exist in 1.1 nor does the digest method with a signature that accepts an array, offset, and length.

11.6 Summary

In this chapter, weve explored the message digest. The facility to calculate a message digest is straightforward and easy to use; the facility to write our own message digest class is equally straightforward. The message digest by itself gives us some comfort about the state of the data it represents, but it does not give us a completely secure system. If we have a shared passphrase or secret key, we can construct a secure message digest that is, a Message Authentication Code. A secure message digest is very similar to a digital signature, which well explore in the next chapter.

Chapter 12. Digital Signatures

In this chapter, we explore the mechanisms of the digital signature. The use and verification of digital signatures is another standard engine that is included in the security provider architecture. Like the other engines weve examined, the classes that implement this engine have both a public interface and an SPI for implementors of the engine. Well start by looking at the interface of the digital signature engine and see how you can create digitally signed objects that you can send between programs. Well continue by looking into the details of digitally signed classes, including the jarsigner tool that creates those classes and how you can deal with those classes programatically. Well conclude by looking at the details of the engine algorithm and how you can implement your own digital signature algorithms.

12.1 The Signature Class

When you handle digital signatures programatically, you perform two operations on them. You create them by taking a piece of data, creating a message digest of the data, and signing the message digest with a private key. The digitally signed data is then transmitted to someone else, who must verify the digital signature by creating a message digest of the data and verifying the signed digest using a public key. All of these operations are embodied within the Signature class java.security.Signature : public abstract class Signature extends SignatureSpi Provide an engine to create and verify digital signatures. The Sun security providers include implementations of this class that generate signatures based on the DSA and RSA algorithms.

12.1.1 Using the Signature Class

As with all engine classes, instances of the Signature class are obtained by calling one of these methods: public static Signature getInstanceString algorithm public static Signature getInstanceString algorithm, String provider Generate a signature object that implements the given algorithm, optionally using the named provider. If an implementation of the given algorithm is not found, a NoSuchAlgorithmException is thrown. If the named security provider cannot be found, a NoSuchProviderException is thrown. If the algorithm string is DSA, the string SHADSA is substituted for it. Hence, implementors of this class that provide support for DSA signing must register themselves appropriately that is, with the message digest algorithm name in the security provider. Once a signature object is obtained, the following methods can be invoked on it: public void final initVerifyPublicKey publicKey Initialize the signature object, preparing it to verify a signature. A signature object must be initialized before it can be used. If the key is not of the correct type for the algorithm or is otherwise invalid, an InvalidKeyException is thrown.