Microsoft Word document.

advertisement
Crypto Applet: An Educational Tool
Robert Rodini
Introduction
My introduction to Cryptography was “MAT 8790: Cryptography” during Villanova’s Summer Session
2007. The text for this course was Cryptography: Theory and Practice by Douglas Stinson. During this
course I found myself writing Java programs to explore the algorithms discussed and to sharpen my
programming skills. By the end of the course I had a couple of the simple cipher systems implemented
in a “uniform” way. By uniform I mean that the APIs for the cipher system adhered to a Java interface
and could be invoked in the same fashion. To those familiar with object oriented programming
concepts, I had implemented a Strategy pattern for Stinson’s cryptosystems.
The project lay dormant until I saw it as an opportunity to release it as an educational tool, and seek
credit for an independent study. Thus was born the Crypto Applet project.
To make it educational, I tried to implement several simple ciphers that a high school student could
absorb without difficulty: Shift, Affine, and Substitution. Hopefully the student’s interest would be
piqued to the point that she may investigate the RSA and ElGamal ciphers, and the mathematics behind
them. The applet’s demo pane permits the student to interact with the ciphers by entering parameters
for the encryption key and various plaintext strings to encrypt with the cipher. The plaintext and
ciphertext values can be displayed “alphabetically,” as per Stinson, or numerically. A numerical display
shows the inner workings of the encryption algorithm more clearly than the alphabetical display.
In the course of the project I learned a great deal about the cipher algorithms, the Java math library, the
Java swing library, and HTML coding. I will share some insights by visiting each cipher and discuss what
I learned doing the implementation.
I also released all source code under the Academic Free License v.3.0. I choose this one from the many
Open Source license choices, because AFL has an academic orientation. Feel free to download the
source into the Eclipse IDE and read the source code.
Educational Content
The Introduction panel contains the user manual, so to speak, for the program. It explains what a cipher
is and how text messages must be converted to numeric values for algorithmic processing. The user
should read the Introduction panel in order to know how to interact with the rest of the program.
Each tab leads to one of five ciphers: Shift, Affine, Substitution, RSA, and ElGamal. Each cipher has
three panels: Theory, Demo, Code. Theory panel sets forth the mathematics that makes the cipher
work. Demo panel permits the user to interact with the cipher. Code panel displays the actual code
within the program.
Suggested Student Exercises

Under what conditions do Shift, Affine, Substitutions yield the same ciphertext value?
1
Crypto Applet: An Educational Tool
Robert Rodini

Give strings to students and have them convert them to trigram values using a calculator. Check
results using Crypto applet.

Give messages to students to encrypt manually and check the results using the applet.

Give encrypted messages to students and have them attempt to decrypt (hint: give cipher too).
Suggested Instructor Exercises

Explain the notation on the theory pages.

Give a detailed explanation of RSA and/or ElGamal mathematics.

Explore the implementation of Java BigInteger library.
Program Technology and Architecture
The applet consists of two jar files: 1) the crypto “engine” (crypto.jar) 2) the Graphical User Interface
(GUI) written in Java Swing (cryptogui.jar). I first considered writing this as a pure web application
(servlets, jsp’s, etc.) but was discouraged by the fact that I would have to find a host that would run the
web application. Villanova’s IT department (UNIT) does not provide this service to students; however,
they do provide content space with few restrictions. This made the choice of Swing/applet for me,
although at the start I did not know Swing programming. I also knew that any user of the application
would have to have the Java 5.0 run-time system loaded into their browser program. This imposes a
barrier to potential users who would have to upgrade to this level of the Java run-time.
The crypto engine can be run standalone from the command line but it doesn’t support user interaction.
My first step in providing a user interface was not to implement a GUI in Swing. I had developed the
engine with pre-defined encryption key parameters and needed to extend the engine with parameter
setting routines. So I implemented a command line interface (cryptoui.jar) to the engine wherein I could
perfect the entry and validation of parameters and exception handling. Since this runs from the
command line, it is not part of the applet, but it was a worthwhile stepping stone. When the command
line version was working properly I undertook the more complex Swing programming. This resulted in
the applet version.
Here is the HTML for the applet invocation:
<applet code="ciphergui.CipherApplet.class" name="Crypto Applet"
archive="crypto.jar,cryptogui.jar"
width=620 height=450 codebase="crypto">
<param name="bgcolor" value="ffffff">
<param name="fontcolor" value="000000">
Your browser is not Java enabled.
</applet>
As you can see there’s not a lot to it, however, I have to make several points.
2
Crypto Applet: An Educational Tool
Robert Rodini
The HTML page with the above code references a nested folder called “crypto.” This is where the two
jar files reside on the server. The entry point for the applet is the CipherApplet class which must be
referenced by package name.
The applet displays both html (Introduction, Theory panels) and text (code panels) within Swing
components. The html and text content can be stored on the server and referenced as external to the
Java code. This meant that if someone wanted to run the applet on their own server, say after making
an enhancement, they had to replicate the content from the original server. To avoid this, I embedded
the html and text within the jar file itself and used Java APIs to load it. Below is an example of how the
Intro pane is displayed:
JEditorPane htmlCode = new JEditorPane();
htmlCode.setContentType("text/html");
htmlCode.setEditable(false);
try {
InputStreamReader br = new
InputStreamReader(getClass().getResourceAsStream("html/intro.html"));
htmlCode.read(br, null);
br.close();
} catch (FileNotFoundException e1) {
e1.printStackTrace();
} catch (IOException e1) {
e1.printStackTrace();
}
The critical API is getResourceAsString which reads from a folder nesting within the jar file itself.
I will have more to say about Java Swing programming later.
On the Difficulty of Naming Things
I’ve been a software engineer my entire career and will attest to what I believe is the most difficult task
– inventing good names during programming. This is especially true for object-oriented programming
where a good design for a class is that fact that the class does one and only one thing. Now this project
is small enough that I feel that I did adhere at least to this design principle. However, I will admit that
I’ve been inconsistent in my naming.
I treat “crypto” and “cipher” interchangeably throughout the program. I think cipher predominates, but
the package names and project names still say “crypto.” Please forgive my inconsistency.
Also I wish I had named “CryptoUI “ as “CryptoCLI” where CLI means “Command Line Interface.” As it
stands “CryptoUI” maybe easily confused with “CryptoGUI.”
Converting Letters to Numbers
There are two utility classes ConvertAlphabet and ConvertTrigramAlphabet whose job is to
translate between alphabetic representation and numeric representation.
3
Crypto Applet: An Educational Tool
Robert Rodini
ConvertAlphabet is used by the simple ciphers which operate on values in the limited range of 0 to
25.
ConvertTrigramAlphabet is used by RSA and ElGamal ciphers which operate on larger values. It
is imperative that these ciphers convert groups of letters (three letters to a trigram) before the ciphers
operate on them. If you simply let RSA and ElGamal operate on individual values in the range 0 to 25
the encrypted values are just a one-for-one scrambling of a plaintext value to a cipher value which is
equivalent to a substitution cipher. To avoid this, the numeric values must be large in absolute value so
a trigram mapping is used. As explained in the applet’s Introduction page the triplet “dog” is mapped to
the numeric value 2398 as follows:
d => 3*(26)2 = 2028
o => 14*(26)1 = 364
g => 6*(26)0 = + 6
2398
I also had to deal with the fact that the entire plaintext value must be a multiple of three. I had the
choice of truncated an extra character or two, or padding the string with a character or two. I chose the
latter using a ‘b’ (think ‘blank’) for the pad character.
I noticed in the course of the project that the complex algorithms produce encrypted values that are
larger than any input or output values. This is shown in the values related to the string “dog” where the
encrypted value is not a three, but a four character string, “BLND.”
This forced me to re-implement the routine int2Trigram routine. The old and new versions are
shown.
/**
4
Crypto Applet: An Educational Tool
Robert Rodini
* Convert an int to a trigram value.
* Example: 3*26^2 + 14*26 + 6 = 2398 =>
* "dog"
*
* @deprecated
*/
private static String int2Trigram_old(int val) {
int i0, i1, i2;
i0 = val / 676; // 676 = 26^2
val = val - (i0 * 676);
i1 = val / 26;
val = val - (i1 * 26);
i2 = val;
return "" + int2Char(i0) + int2Char(i1) + int2Char(i2);
}
/**
* Convert an int to a trigram value.
* Example: 3*26^2 + 14*26 + 6 = 2398 => "dog"
*
* @param val numeric value to convert to a trigram.
*/
private static String int2Trigram(int val) {
StringBuffer buf = new StringBuffer();
int divisor = 26;
int b = 0;
int i;
for (i=0; val>0; i++)
{
b = val % 26;
buf.append((char) (b + (int) 'a'));
val = val / divisor;
}
if (i < 3) // covers weird boundary case when trigram starts with 'a'
{
b = val % 26;
buf.append((char) (b + (int) 'a'));
}
return buf.reverse().toString();
}
This proves another programming adage first espoused by the rock band Jethro Tull: “Nothing Is Easy.”
Shift Cipher
The Shift cipher is the simplest of the ciphers. For this reason I chose this as the example in the
introduction. The encryption algorithm is straightforward:
public int[] encrypt(int[] ba) {
int len = ba.length;
int[] cipher_ba = new int[len];
for (int i=0; i < len; i++)
5
Crypto Applet: An Educational Tool
Robert Rodini
{
cipher_ba[i] = (ba[i] + SHIFT) % 26;
}
return cipher_ba;
}
Programming Notes:
 The parameter ba contains the numeric values for the plaintext to be encyrpted.
 A new array cipher_ba holds the numeric values following the encryption.
 ‘%’ is the modulus operator in Java.
The decryption algorithm is almost as straightforward; however, Java performs signed arithmetic on
int (integer) values. So the result of the modulus operator may be a negative number.
public int[] decrypt(int[] ba) {
int len = ba.length;
int mod;
int[] plain_ba = new int[len];
for (int i=0; i < len; i++)
{
mod =(ba[i] - SHIFT) % 26;
// Java modular arithmetic is signed so convert negative residues.
mod = mod <0 ? mod+26 : mod;
plain_ba[i] = mod;
}
return plain_ba;
}
Programming Notes:
 The conditional operator, ?: , acts like an in-line if statement. Following ‘?’ is the true value;
following ‘:’ is the false value.
Affine Cipher
The Affine cipher is a little more sophisticated than the Shift cipher. I won’t present the
encryption/decryption algorithm, but will comment on the parameter entry. Parameter entry is made in
the GUI part of the applet. The Affine cipher just validates that A, the multiplicative factor, is relatively
prime to 26. And that B, the shift factor, is between 0 and 25 inclusive.
To validate A, and to find its inverse modulus 26, I pre-calculated all of the numbers that are relatively
prime to 26 and their inverses. Show below is the validation.
private final int[] validA = { 0, 1, 0, 3, 0, 5, 0, 7, 0, 9, 0, 11, 0, 0,
0, 15, 0, 17, 0, 19, 0, 21, 0, 23, 0, 25 };
private final int[] validAInverse = { 0, 1, 0, 9, 0, 21, 0, 15, 0, 3, 0,
19, 0, 0, 0, 07, 0, 23, 0, 11, 0, 5, 0, 17, 0, 25 };
/**
* Validate and set the multiplicative value for the cipher.
*
* @param valA is the candidate multiplicative value. It must be
relatively prime to 26.
6
Crypto Applet: An Educational Tool
Robert Rodini
* @throws IllegalArgumentException.
*/
public void setA(int valA) throws IllegalArgumentException
{
if (valA < 0 || valA > 25)
{
throw new IllegalArgumentException("A value must be in [0..25]");
}
if (validA[valA] == 0)
{
throw new IllegalArgumentException(
"A value must be relatively prime to 26");
}
A = valA;
A_INVERSE = validAInverse[valA];
}
I could have used the Euclidean Algorithm to determine if A is relatively prime to 26 and another
algorithm to find its inverse, but a table lookup works fine. This demonstrates the classic time/space
tradeoff that one encounters in computer programming frequently.
Substitution Cipher
The reader should be familiar with Substitution cipher as it is the familiar cryptogram puzzle found in
newspapers. The only tricky part of its implementation was inputting the permutation that is to be used
as the encryption key. “That’s simple,” I thought, “just have the user type the 26 letters of the alphabet
in random order and use that as the permutation.”
Well, I wanted to give feedback while the user was typing so my first implementation was to display a
label after the input field showing the letters that had not been entered. This works fine if the user
works methodically from left to right, but as I tested the implementation, I found that I sometimes used
the mouse to reposition the cursor. This wrecked havoc (as did use of CTRL-C, and CTRL-V) on the
implementation as I soon discovered that I had to implement a word processor in order to echo the
unused characters accurately. So in the second implementation, I wait until the entire permutation is
entered before validating it.
A good way to verify the implementation is to enter a permutation (just following the keyboard left to
right from top to bottom) and then enter the alphabet as the string to encrypt. You will see something
like this.
7
Crypto Applet: An Educational Tool
Robert Rodini
RSA Cipher
RSA is the first cipher that introduces high order mathematics. The algorithm requires two large prime
numbers to be entered by the user. Validation of the primes and RSA algorithm implementation are
made ridiculously simple by the Java BigInteger library. When I discovered the methods of this
library I realized that it was designed with RSA in mind. The methods I use for validation, encryption,
and decryption are:




isProbablePrime
multiply
modInverse
modPow
The encryption and decryption algorithms are each implemented in only 12 lines of code! However,
there is a flaw in the implementation (discovered through testing) due to high-order truncation during
an assignment operation. This all depends on the RSA parameter values, and bad values are: P=68879,
Q=99397, B=487. B’s computed inverse is A=4287659743. The faulty assignment takes place on this line:
// potential error here. long value may be truncated by cast to int
cipher_ba[i] = (int) y.longValue();
El Gamal Cipher
When I first encountered the El Gamal cipher I dismissed it for commercial purposes because, by design,
it doubles the length of the ciphertext value. Since ciphers are intended for communication purposes,
this means the transmission must be twice the length, say, of an RSA ciphertext. After working with El
Gamal I now see that this negative can be viewed as a positive since the use of a random variable makes
the cipher that more difficult to decrypt.
In addition to the encryption keys there is a random value, called K, that is used by the
encryption/decryption algorithm. In my first implementation I had the user enter this value and use it
repeatedly. Then I realized that I could get closer to a one-time pad by having this value represent the
8
Crypto Applet: An Educational Tool
Robert Rodini
seed to a random number generator. This seed is given to the Java Random library and as each trigram
is encrypted, a new K value is generated by the Random class.
Another interesting aspect is that a primitive element (root) of the private key, called ALPHA, must be
validated. My implementation is simply to generate powers of the element modulus P until finally (and
this is guaranteed) it is equal to 1:
public void setALPHA(int alpha) throws IllegalArgumentException
{
// Validate that alpha is a primitive element for A.
BigInteger valAlpha = new BigInteger(Integer.toString(alpha));
// Here we have alpha^1
BigInteger valAlphaPower = valAlpha;
int pow;
for (pow = 2; pow < p; pow++) {
valAlphaPower = valAlphaPower.multiply(valAlpha);
BigInteger val = valAlphaPower.mod(P);
if (val.equals(BigInteger.ONE)) {
break;
}
}
if (pow < p - 1) {
throw new IllegalArgumentException("ALPHA must be a primitive root for P");
}
ALPHA = alpha;
BigInteger valBETA = (new BigInteger(Integer.toString(alpha))).modPow(A, P);
BETA = valBETA.intValue();
}
If ALPHA is a primitive root then the power is one less than the prime P.
This implementation proves to be computationally intensive and pins the processor for a few seconds.
See how long it takes on your machine with these values:
 P = 31847
 A = 7899
 ALPHA =5
 SEED=1234
I will have more to say about this computation in the Swing Programming section.
Swing Programming
As I mentioned I did not know any Swing programming at the beginning of the project. I did have
experience developing GUI programs in Visual Basic so “event driven” programming was in my
background.
I bought an eleven hundred page O’Reilly book titled Java Swing that was no help whatsoever since it
was too low-level. I found the tutorials and sample code on Sun’s website to be most useful. The tool
that really saved the day was the Visual Editor plugin for Eclipse. This plugin is barely maintained by the
9
Crypto Applet: An Educational Tool
Robert Rodini
Eclipse community, but it still works like a charm. You may have difficulty finding a version compatible
with Ganymede.
The most challenging area of the GUI programming was the validation of the parameters with the goal
of giving feedback to the user. Swing generates an event when the Enter key is pressed, the only event
that the program initially responded to. I immediately discovered that I, myself, was using the Tab key
to move between fields, so I decided to program a Tab event the same as an Enter event. Then the first
time I observed another user (my son) interact with the program, he used the mouse to move from field
to field! I never implemented the mouse event, but I do give feedback in the form of a check mark to
indicate that the parameter has been validated. Hopefully, this conditions the user to use the correct
input technique.
The very last parameter validation that I implemented was the primitive element for ElGamal
encryption. I was hoping to find an efficient algorithm for this but ended up with a brute force
enumeration of powers. This is disconcerting to the user because all of the other parameters are
validated almost instantaneously (thanks again BigInteger!).
I thought of changing the label for ALPHA entry to “WAIT...WAIT…” below:
private void actionALPHAPerform() {
String aVal = jTextALPHA.getText();
String aError = null;
int val = 0;
try {
val = Integer.parseInt(aVal);
jLabelALPHA.setText("WAIT...WAIT…");
cipher.setALPHA(val);
} catch (NumberFormatException ex) {
aError = "Please enter a number.";
} catch (IllegalArgumentException ex) {
aError = ex.getMessage();
}
jLabelALPHA.setText("Enter primitive element.");
This change had no effect whatsoever. Why? Some investigation led to this passage in the Swing
documentation:
… As for any applet, you should never perform time-consuming initialization in the init() or start()
method; instead, you should start a thread that performs the time-consuming task…
This passage indirectly hints at the need for starting a separate thread on which to call the setALPHA
method. This I will leave as an enhancement to the reader; however, if you download the code and see
incomprehensible thread creation logic in this area, than you can assume that I have risen to the
challenge myself.
Finally I want to comment on the HTML displayed within the JEditorPane class. My first
implementation was to display scanned images of the Cryptosystem descriptions from Stinson’s book. I
10
Crypto Applet: An Educational Tool
Robert Rodini
sought permission from the publisher Chapman & Hall/CRC but was told that these images could only be
displayed on a password protected website. This was too restrictive so I translated the image content
to HTML version 3.2 (HTML4 was not allowed due to the fact that JEditorPane implements only v. 3.2).
Note that it is the applet that renders the HTML displayed on the screen, not your (hopefully more
modern) browser.
To demonstrate what HTML v3.2 looks like here is some of the HTML for ElGamal theory:
<html>
<b>Cryptosystem: ElGamal Public-Key</b>
<br><br>
Let <font face="Georgia"><i>p</i></font>, be a prime such that the
<body>Discrete Logarithm</b>
problem in <font face="Georgia">(Z<sub>p</sub><sup>*</sup>,⋅)</font> is
infeasible,
and let α ∈ <font face="Georgia">Z<sub>p</sub><sup>*</sup></font>
be a primitive element.
Let <font face="Georgia"><i>P = Z<sub>p</sub><sup>*</sup></i></font>,
<font face="Georgia"><i>C = Z<sub>p</sub><sup>*</sup> x
Z<sub>p</sub><sup>*</sup></i></font>
, and define
<br><br>
<div align="center"> <font face="Georgia">
<i>K</i> = {(p,α,a,β) : β ≡ α<sup>a</sup> (mod
p)}</font>.
</div>
<br><br>
The values <font face="Georgia">p, α</font> and <font
face="Georgia">β</font> are the public key,
and <font face="Georgia">a</font> is the private key.
<br><br>
This is not the most readable or maintainable HTML, but it will do in a pinch.
Tools
I used the following tools to develop the Crypto Applet:
 Eclipse (Ganymede version)
 Visual Editor plugin (org.eclipse.ve)
 Mathematica v.7 Student Edition
 Microsoft FrontPage 2003 Ed.
I used Mathematica to check the program’s calculations, especially when I received unexpected results.
FrontPage is the University approved tool for deploying content to the student’s website.
Conclusion
I hope you enjoy the Crypto applet in its current form but I will immediately suggest these
improvements:
11
Crypto Applet: An Educational Tool
Robert Rodini



More educational content
Addition of new ciphers
Conversion to a plugin architecture
The first two bullets are self-explanatory. A plugin architecture would permit the dynamic binding of
new ciphers at run-time. You would prove yourself to be a first-class Java programmer by implementing
this architecture.
Comments and feedback are welcome.
Bibliography
Castro, E. (2003). HTML for the World Wide Web (5th Edition). Berkeley: Peachpit Press.
Eckstein, R., Loy, M., & Wood, D. (1998). Java Swing. Sebastopol: O'Reilly & Associates.
Flanagan, D. (2005). Java in a Nutshell (5th Edition). Sebastopol: O'Reilly Media.
Flanagen, D. (2000). Java Examples in a Nutshell (2nd Edition). Sebastopol: O'Reilly & Associates.
Sierra, K., & Bates, B. (2005). Head First Java (2nd Edition). Sebastopol: O'Reilly Media.
Stinson, D. (2006). Cryptography: Theory and Practice (Third Edition). Boca Raton: Chapman & Hall/CRC.
12
Download