Java Exercise

Back to workshop details

Introduction
HcryptoJ is Java API for historical cryptology. It contains classes for simple ciphers, such as Caesar cipher and Vigenere cipher, and analysis tools for breaking ciphers, such as Caesar analyzer.

In this exercise, we will download HcryptoJ from Sourceforge and make changes to its codebase.

Read this overview of HcryptoJ.

For the tutorial portion of this exercise we will work together as a whole group. However, for exercise 1 and 2, you will break up into small 3-4 person teams. Each team should set up their own IRC channel to share their thoughts and comments about the project. And each team should set up their own PasteBin session to share code snippets if necessary.

If you have general questions -- i.e., non-team-related -- post them on the HFOSS IRC channel.

Getting Started Tutorial
 Set up a working directory for this project and download the HcryptoJ source code into your directory.

Extract the source code from the jar file: $ jar xvf hcrypto-hg-repo.jar

This will set up the following directory structure, where source code is stored in src and executable Java code in classes:

-rw-r--r-- 1 rmorelli  rmorelli    35147 Dec  8  2009 LICENSE.txt drwxr-xr-x 3 rmorelli  rmorelli      102 May 17 16:03 META-INF -rw-r--r-- 1 rmorelli  rmorelli     3659 May 17 16:02 README.txt -rw-r--r-- 1 rmorelli  rmorelli      742 May 17 15:31 build.xml drwxr-xr-x 6 rmorelli  rmorelli      204 May 17 15:36 classes drwxr-xr-x 7 rmorelli  rmorelli      238 May 17 10:32 data -rw-r--r--@ 1 rmorelli rmorelli  3299858 May 17 16:22 hcryptoj-hg-repo.jar drwxr-xr-x 6 rmorelli  rmorelli      204 May 17 15:28 src

Try running TestCipher from the command line: // Usage: //java  classpath            TestCipher           algorithm    keyspec      plaintext [-d] $ java -classpath ./classes/ applications.TestCipher Caesar 5/az+AZ/az+AZ "This is a test of Caesar" A keyspec, short for key specification, specifies the Caesar shift, followed by the plaintext alphabet (lower and upper case letters) and the cihpertext alphabet. The -d option performs a decryption.

Try running FileCipher from the command line: // Usage: java FileCipher cipher keyspec -e|-d infile outfile [encoding] $ java -classpath ./classes applications.FileCipher Substitution keyword/ascii/ascii -e README.txt README.encrypted.txt $ java -classpath ./classes applications.FileCipher Substitution keyword/ascii/ascii -d README.encrypted.txt README.decrypted.txt Play around with CryptoToolJ, a GUI interface. $ java -classpath ./classes applications.cryptotoolj.CryptoToolJ & Things to try:  Decrypt README.encrypted.txt: File > Open > Select Substitution Cipher and key > Decrypt Create a cipher engine: File > New Cipher > Select Cipher and key Use a plugin cipher: File > New Cipher > Select a plugin cipher and use it Analyze a Caesar cipher: File > New Cipher > Select Caesar and key > Encrypt Analysis > Caesar Analyzer  

HcryptoJ Design Details
The following UML diagram shows the top-level classes of the HcryptoJ hierarchy. Every cipher consists of two basic components, a cipher engine, which performs the encryption and decryption algorithms, and a cryptographic key, which contains the secret data used by the engine. To create your a new cipher, you would define subclasses of BlockCipher and HistoricalKey.



Exercise 1: Create a Null Cipher Plugin
One way to extend HcryptoJ would be to add to its code base by defining a new cipher and adding it to HcryptoJ's hierarchy. You can see what ciphers come with the package by listing the engines directory:

109add49afd3:hcrypto-download rmorelli$ ls -l src/hcrypto/engines/ total 280 -rw-r--r-- 1 rmorelli  rmorelli   5966 Nov 12  2009 AffineEngine.java -rw-r--r-- 1 rmorelli  rmorelli   4606 Nov 12  2009 AffineKey.java -rw-r--r-- 1 rmorelli  rmorelli   4489 Nov  4  2009 CaesarEngine.java -rw-r--r-- 1 rmorelli  rmorelli   4391 Dec  8  2009 CaesarKey.java -rw-r--r-- 1 rmorelli  rmorelli   1571 Oct 29  2009 NullEngine.java -rw-r--r-- 1 rmorelli  rmorelli   1714 Oct 29  2009 NullKey.java -rw-r--r-- 1 rmorelli  rmorelli   6585 Nov  4  2009 PlayfairEngine.java -rw-r--r-- 1 rmorelli  rmorelli   9698 Dec  3  2009 PlayfairKey.java -rw-r--r-- 1 rmorelli  rmorelli   7168 Nov  4  2009 PolySubstitutionEngine.java -rw-r--r-- 1 rmorelli  rmorelli   9514 Dec  8  2009 PolySubstitutionKey.java -rw-r--r-- 1 rmorelli  rmorelli   6290 Nov  4  2009 RailfenceEngine.java -rw-r--r-- 1 rmorelli  rmorelli   2848 Nov 12  2009 RailfenceKey.java -rw-r--r-- 1 rmorelli  rmorelli   4218 Nov  4  2009 SubstitutionEngine.java -rw-r--r-- 1 rmorelli  rmorelli  10236 Dec 13  2009 SubstitutionKey.java -rw-r--r-- 1 rmorelli  rmorelli   5349 Nov  4  2009 TranspositionEngine.java -rw-r--r-- 1 rmorelli  rmorelli   3802 Nov 12  2009 TranspositionKey.java -rw-r--r-- 1 rmorelli  rmorelli   5694 Nov  4  2009 VigenereEngine.java -rw-r--r-- 1 rmorelli  rmorelli   4381 Nov  4  2009 VigenereKey.java

You can also create your own cipher and add it as a plugin. Plugins must be defined in the plugins package and added to the src/plugins folder. Currently, the plugins folder contains a Caesar cipher as an example: 109add49afd3:hcrypto-download rmorelli$ ls -l src/plugins/ total 40 -rw-r--r-- 1 rmorelli  rmorelli  4481 Dec 13  2009 CaesarEngine.java -rw-r--r-- 1 rmorelli  rmorelli  4383 Dec 13  2009 CaesarKey.java -rw-r--r-- 1 rmorelli  rmorelli  2633 May 17 14:47 PluginProvider.java

In addition to the CaesarEngine and CaesarKey classes, it is necessary to add an entry for your plugin to the PluginProvider class. This is how the run-time system finds new ciphers and loads them into its memory.

Follow these steps to create a Null cipher.  Make a copy of CaesarEngine and CaesarKey and rename them to NullEngine and NullKey respectively, saving them both in the plugins directory.

<li>Edit Provider.java by adding an entry for your Null cipher to its constructor. It should look like this when you are done: public PluginProvider(String name) { this.name = name; put("Caesar", "plugins.CaesarEngine","plugins.CaesarKey"); put("Null", "plugins.NullEngine","plugins.NullKey"); } <li>Edit NullEngine.java and NullKey.java and do a global replace of the word Caesar with Null. <li>Make the following edits to NullEngine.java:  <li>Modify the engineEncode and engineDecode methods, which perform the actual encryption transformations, so that they perform no transformation of the input text: public String engineEncode(String s ) throws Exception { return s;   } public String engineDecode( String s ) throws Exception { return s;   } </ul> <li>Make the following edits to ''NullKey.java':  <li> Modify the DEFAULT_KEY_DESCRIPTOR_PROMPT_STRING to be whatever you like. It will basically be ignored in Null cipher. public final static String DEFAULT_KEY_DESCRIPTOR_PROMPT_STRING = "whatever"; <li>Modify the DEFAULT_KEYWORD_STRING to be whatever you like. It will basically be ignored in Null cipher. public final static String DEFAULT_KEYWORD_STRING = "blah";

<li>Modify the init method to remove any references to the Caesar shift. It should look like this when you're done: public void init(String keyspec) throws Exception { initKey(keyspec, false); // Inherited from superclass this.blocksize = 1; }

</ul> <li>Compile the Java files that you created or modified. The following command from the main hcryptoj directory will compile the files and place the classes in the correct package folder (-d .)" $ ant build <li>Run CryptoToolJ from the main hcrypto directory: $java -classpath ./classes applications.cryptotoolj.CryptoToolJ & </ol>

Exercise 2: Create Your Own Cipher Plugin
Create your own simple cipher and add it as a plugin to CryptoToolJ. Some possibilities:

 <li>Create a simple substitution cipher that translates lowercase a to z using a permutation of the plaintext alphabet. Use a keyword to create a unique permutation of the alphabet. For this cipher you would want to set alphabetRangeOptions = "10000/10000" to restrict messages to the lowercase alphabet. The DEFAULT_KEY_DESCRIPTOR_PROMPT_STRING should be "a keyword" and the DEFAULT_KEYWORD_STRING should be something like "keyword". For this cipher the blocksize should be 1. The engineEncode and engineDecode methods will be passed a String of length 1. Your code in these methods should perform the mapping from plain to cipher alphabet or vice versa. Your engineInit method or your init method in the key class should create arrays to perform the mappings. For ideas on this, take a look at the built-in substitution cipher. </li>

<li>Create a transposition cipher that rearranges blocks of plaintext letters into ciphertext. In this case, the blocksize could be determined by the length of the keyword or it could be fixed. The transposition could be as simple as a reversal or a cycle of the block or it could be specified by the keyword. For example the keyword "51423" could specify how to arrange a block of five letters. See the built-in transposition cipher for an example. </li>

<li>Make up your own cipher or modify one of the other built-in examples. </li> </ul>