9.3. Implementing a MessageDigest ClassIf you want to write your own security provider, you have the option of creating your own message digest engine. Typically, you'd do this because you want to ensure that a particular algorithm like SHA is available regardless of who the default security provider is; if you have a mathematics background, it's conceivable that you might want to implement your own algorithm. In order to implement a message digest algorithm, you must provide a concrete subclass of the MessageDigest class. This essentially entails providing an implementation of most of the public methods we've just looked at. Although the public methods are not declared abstract, they typically do nothing more than call an internal (protected) method to accomplish their task. The MessageDigest class exists in both Java 1.1 and 1.2,[1] which is why it extends its SPI (see Chapter 8, "Security Providers"). For our example, we'll directly subclass the MessageDigest class so that the resulting example will work under both releases, but remember that in 1.2 you have the option of extending the MessageDigestSpi class directly.
There is a single constructor in the MessageDigest class that is available to implementors:
In order to write a message digest class, you must implement each of the following methods:
Each of these methods corresponds to a public method we just looked at, with the name of the public method preceded by the word "engine". The public methods that do not have a corresponding method in this list are fully implemented in the base class and do not need to be implemented in the message digest subclass. We'll show a simple implementation of a message digest class here. This implementation is based on a hash algorithm that produces a 4-byte output. As bytes are accumulated by this algorithm, they are stored into a 4-byte value (that is, an int); when this value has all four bytes filled, it is XOR-ed to another integer that accumulates the hash. Class Definitionpackage com.xyz; public class XYZMessageDigest extends MessageDigest implements Cloneable { private int hash; private int store; private int nBytes; public XYZMessageDigest() { super("XYZ"); engineReset(); } public void engineUpdate(byte b) { switch(nBytes) { case 0: store = (b << 24) & 0xff000000; break; case 1: store |= (b << 16) & 0x00ff0000; break; case 2: store |= (b << 8) & 0x0000ff00; break; case 3: store |= (b << 0) & 0x000000ff; break; } nBytes++; if (nBytes == 4) { hash = hash ^ store; nBytes = 0; store = 0; } } public void engineUpdate(byte b[], int offset, int length) { for (int i = 0; i < length; i++) engineUpdate(b[i + offset]); } public void engineReset() { hash = 0; store = 0; nBytes = 0; } public byte[] engineDigest() { while (nBytes != 0) engineUpdate((byte) 0); byte b[] = new byte[4]; b[0] = (byte) (hash >>> 24); 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 isn't surprising given the fact that the algorithm itself is too simple to be considered an effective digest algorithm. The major points to observe are:
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, "Security Providers", we can change our Send class above to use our new digest algorithm: Class Definitionpublic class SendXYZ { public static void main(String args[]) { try { Security.addProvider(new XYZProvider()); FileOutputStream fos = new FileOutputStream("test.xyz"); MessageDigest md = MessageDigest.getInstance("XYZ"); ObjectOutputStream oos = new ObjectOutputStream(fos); 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.update(buf); oos.writeObject(data); oos.writeObject(md.digest()); } catch (Exception e) { System.out.println(e); } } } Similar changes to the Receive class will allow us to accept the message that we've saved to the file test.xyz. Copyright © 2001 O'Reilly & Associates. All rights reserved. |
|