But what if you need to implement your own digest or cipher? JCE allows to add your own cryptographic provider to the framework, which is what we will do in this tutorial.
Source code for this tutorial is available on googlecode as a single zip archive, as a Team Project Set or you can checkout the SVN projects directly.
Step 1: Create a digest implementation
We will implement a simple digest that will XOR all bytes of a message and therefore return a 1 byte checksum.
Start by creating a new Java Project named com.example.jce.provider. To implement a digest we need to extend MessageDigestSpi. Implement com.example.jce.provider.XORDigest as follows:
package com.example.jce.provider; import java.security.MessageDigestSpi; public class XORDigest extends MessageDigestSpi { private byte mChecksum = 0; public XORDigest() { } @Override protected void engineUpdate(byte input) { mChecksum ^= input; } @Override protected void engineUpdate(byte[] input, int offset, int len) { for (int index = offset; index < offset + len; index++) engineUpdate(input[index]); } @Override protected byte[] engineDigest() { return new byte[] { mChecksum }; } @Override protected void engineReset() { mChecksum = 0; } }Step 2: Create a JCE provider
To register our digest in the JRE we need to use a provider. This provider is used by the JCE as an entry point to locate our Digest class. Create a new class com.example.jce.provider.CryptoProvider:
package com.example.jce.provider; import java.security.Provider; public class CryptoProvider extends Provider { private static final long serialVersionUID = -67123468605911408L; public CryptoProvider() { super("SimpleCrypto", 1.0, "XOR digest v1.0"); put("MessageDigest.XOR", XORDigest.class.getName()); } }Finally we need to register this provider in our runtime. There are several ways to do this, here we will use the dynamic approach as we do not want to alter our JRE install folder. Registration is handled by the Security class:
Security.addProvider(new CryptoProvider());
Step 3: Using our provider
Lets see our provider in action:
public static void main(String[] args) { Security.addProvider(new CryptoProvider()); try { MessageDigest digest = MessageDigest.getInstance("XOR"); byte[] checksum = digest.digest(new byte[] { 0x01, 0x23, 0x45 }); System.out.println("Checksum: 0x" + Integer.toHexString(checksum[0])); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } }First we are registering our provider as explained in step 2. Afterwards we create a new digest and feed some data to it. The checksum you get should be 0x67.
Very useful article!
ReplyDelete