The Java Provider Architecture by Paul Tremblett Example 1: ------------- PROVIDER # 1 SUN version 1.2 info: SUN (DSA key/parameter generation; DSS signing; SHA-1, MD5 digests, SecureRandom) name: SUN version: 1.2 string: SUN version 1.2 ------------- PROVIDER # 2 SunJCE version 1.2 info: SUN JCE Provider (implements DES, Triple DES, PBE, Diffie-Hellman) name: SunJCE version: 1.2 string: SunJCE version 1.2 Example 2: com/ com/beechwood/ com/beechwood/crypto/ com/beechwood/crypto/provider/ com/beechwood/crypto/provider/Corbett.class com/beechwood/crypto/cipher/ com/beechwood/crypto/cipher/Enigma.class com/beechwood/crypto/cipher/EnigmaMachine.class com/beechwood/crypto/cipher/EnigmaRotor.class com/beechwood/crypto/cipher/EnigmaRotorTrippedException.class com/beechwood/crypto/cipher/EnigmaReflector.class com/beechwood/crypto/spec/ com/beechwood/crypto/spec/EnigmaParameterSpec.class com/beechwood/crypto/interfaces/ com/beechwood/crypto/interfaces/EnigmaParams.class Example 3: ------------- PROVIDER # 1 SUN version 1.2 info: SUN (DSA key/parameter generation; DSS signing; SHA-1, MD5 digests, SecureRandom) name: SUN version: 1.2 string: SUN version 1.2 ------------- PROVIDER # 2 SunJCE version 1.2 info: SUN JCE Provider (implements DES, Triple DES, PBE, Diffie-Hellman) name: SunJCE version: 1.2 string: SunJCE version 1.2 ------------- PROVIDER # 3 Corbett version 1.0 info: Provider For Dr. Dobb's Article name: Corbett version: 1.0 string: Corbett version 1.0 Listing One package com.beechwood.crypto.cipher; import java.security.SecureRandom; public class EnigmaRotor { private int notchIndex; private int startPosition = 0; private int currentIndex = 0; private int[] b = new int[256]; private int[] f = new int[256]; public EnigmaRotor(long seed, int notchIndex) { this.notchIndex = notchIndex; int fx = 0; int bx; for (int i = 0; i < 256; ++i) f[i] = b[i] = -1; SecureRandom r = new SecureRandom(); r.setSeed(seed); byte[] rb = new byte[1]; for (int i = 0; i < 256; ++i) { r.nextBytes(rb); bx = rb[0] & 0xff; if (b[bx] < 0) { b[bx] = fx; } else { bx = (bx + 128) % 256; while (true) { if (bx > 255) bx = 0; if (b[bx] < 0) break; bx++; } b[bx] = fx; } f[fx] = bx; fx++; } } public void setStartingPosition(int startPosition) { this.startPosition = currentIndex = startPosition; } public void advance() throws EnigmaRotorTrippedException { currentIndex++; if (currentIndex > 255) { currentIndex = 0; } if (currentIndex == notchIndex) { throw new EnigmaRotorTrippedException("notch at " + notchIndex + " tripped"); } } public int processByte(int i, boolean forward) { int ri; int ix; if (forward) { ix = (i + currentIndex) % 256; ri = b[ix]; } else { ix = i; ri = (f[ix] - currentIndex + 256) % 256; } return ri; } } Listing Two package com.beechwood.crypto.cipher; public class EnigmaRotorTrippedException extends Exception { public EnigmaRotorTrippedException() { super(); } public EnigmaRotorTrippedException(String msg) { super(msg); } } Listing Three package com.beechwood.crypto.cipher; import java.security.SecureRandom; public class EnigmaReflector { int[] contacts = new int[256]; public EnigmaReflector(long seed) { byte[] rb = new byte[1]; int[] mi = new int[256]; for (int i = 0; i < 256; ++i) mi[i] = -1; SecureRandom r = new SecureRandom(); r.setSeed(seed); int[] f = new int[2]; for (int i = 0; i < 128; ++i) { for (int j = 0; j < 2; ++j) { r.nextBytes(rb); int ix = rb[0] &0x3f; while (true) { if (mi[ix] < 0) { mi[ix] = 1; f[j] = ix; break; } ++ix; if (ix > 255) { ix = 0; } } } contacts[f[0]] = f[1]; contacts[f[1]] = f[0]; } } public int reflect(int i) { return contacts[i]; } } Listing Four package com.beechwood.crypto.cipher; public class EnigmaMachine { EnigmaRotor[] rotors; int rotorCount; EnigmaReflector reflector; public EnigmaMachine(EnigmaRotor[] rotors, EnigmaReflector ref) { this.rotors = rotors; rotorCount = rotors.length; reflector = ref; } protected void processMessage(byte[] in, int inOffset, byte[] out, int outOffset, int len) { int ox = 0; for (int i = inOffset; i < len; ++i) { for (int rotorIndex = 0; rotorIndex < rotorCount; ++rotorIndex) { try { rotors[rotorIndex].advance(); break; } catch (EnigmaRotorTrippedException erte) { } } int ic = ((int)in[i]) & 0xff; for (int k = 0; k < rotorCount; ++k) { ic = rotors[k].processByte(ic, true); } ic = reflector.reflect(ic); for (int k = rotorCount - 1; k >= 0; --k) { ic = rotors[k].processByte(ic, false); } out[ox++] = (byte)ic; } } } Listing Five package com.beechwood.crypto.interfaces; public abstract interface EnigmaParams { public int[] getNotchPositions(); public int[] getStartPositions(); public int getRotorCount(); } 5