http://www.developer.com/

## Public Key Cryptography 101 Using JavaDecember 14, 2004 Java Programming, Notes # 727 - Preface
- Background Information
- Preview
- Discussion and Sample Code
- Run the Programs
- Summary
- What's Next
- Complete Program Listings
## Preface
This is the first lesson in a series designed to teach you something about
the inner workings of cryptography using Java. Hopefully, when you finish
studying the lessons in this series, you will have learned a little about what goes on
The lessons in this series do not provide instructions on how to use the
Java Cryptography Extension
The programs that I will provide and explain in this series of lessons are
not intended to be used for production cryptography. If you need to do
cryptography using Java, you should use
Sun's Java Cryptography Extension The programs that I will provide in this series are intended to help you to experiment with and to learn about various cryptographic algorithms and to gain a better understanding of how they work, and why they do what they do.
You may find it useful to open another copy of this lesson in a separate browser window. That will make it easier for you to scroll back and forth among the different figures and listings while you are reading about them.
I will provide some of the theoretical basis for cryptographic algorithms while discussing the lessons in this series. In addition, I will show you how to implement several common cryptographic algorithms in Java. I will also discuss and illustrate some of the modern uses of cryptography, such as the use of digital signatures. ## Background InformationCryptography in one form or another has been around throughout history. Even in pre-biblical times, governments had a need to exchange messages in secret.
According to Wikipedia,
encryption."
Confirming what I alluded to earlier,
Wikipedia tells us,
Bringing the field of cryptography up to date,
Wikipedia tells us,
Although this series of lessons won't involve cryptanalysis in any
significant way, it won't hurt to learn the meaning of the term anyway.
Wikipedia tells us,
The lessons in this series will present and explain programs that implement cryptographic algorithms intended to achieve secure communications between two parties. These algorithms fall into two broad categories: - Public
*(asymmetric)*key cryptography - Symmetric key cryptography
The first several lessons will deal with public key cryptography. Subsequent lessons will deal with symmetric key cryptography.
Many modern approaches to data encryption operate by passing the data along
with an Operating in the reverse direction,
The difference between public With symmetric key cryptography, a single secret key is used both to encrypt and to decrypt the data. Thus, both parties to the communication must have access to the same secret key value. The distribution and management of such secret keys can be problematic, and has probably been a source of work for spies throughout history. With asymmetric key cryptography, there are two keys. One is used to
encrypt the data and the other is used to decrypt the data. Thus, one of
the keys Many of the key-management and distribution problems associated with symmetric key cryptography are alleviated through the use of public key cryptography.
This and the next several lessons will deal with a particular asymmetric key algorithm known as the RSA algorithm. This algorithm is named after the original authors, R.L. Rivest, A. Shamir, and L. Adleman. If this lesson sparks your interest in cryptography, you will most certainly want to read their paper describing the algorithm in full.
In their paper, the authors point out that One consequence of this is a significant easing of key management problems relative to symmetric key cryptography. For example, couriers or other secure means are not needed to exchange keys. The sender of the message can encipher the message using the intended recipient's public encryption key. However, only the intended recipient can decipher the message using his private and secret decryption key.
A second important consequence is that a message can be I will discuss the Java implications of this in the next lesson in this series.
Here is the author's brief description of the mathematical encryption process embodied in the RSA algorithm:
As you will see, Java is particularly well suited to the implementation of
this process through the use of methods of the
I will defer the question of security to the authors of the algorithm and
others who have published material in this area. However, the authors do point out that
## Preview
The RSA encryption algorithm consists of two major parts. One part involves performing the mathematical operations required to create the two keys, e and d, and the divisor n. Although not difficult to program, this is the most obscure part from the viewpoint of understanding the algorithm. This operation only has to be done once to establish the public/private key pair and the divisor for each individual user.
The second part involves using the two keys and the divisor to encipher and decipher messages. This must be done for each message, and therefore is an area where computational efficiency may be of concern. The programs that I will provide to perform this operation have not been optimized for efficiency. Rather, they were written for instructional purposes only. As mentioned earlier, you should not attempt to use these programs for production cryptography. If you need a Java program to do public-key cryptography, you should develop that program using Sun's Java Cryptography Extension.
I have read that symmetric algorithms tend to be more computationally efficient than asymmetric algorithms for cases involving large amounts of data. I can neither confirm nor deny that. However, I am aware that in some business transactions involving large amounts of data, an asymmetric approach is used first to distribute a secret symmetric key to both parties and the encryption/decryption process then switches to the use of a symmetric key algorithm.
I will present and discuss four programs in this lesson. The first
program named
The second program is essentially a conversion of the first program from With this program, the maximum size problem that you can solve depends on how long you are willing to wait for a solution to develop. On my computer, a few seconds are required to reach a solution for n = 77. I have never had the patience to wait for the solution for n = 399. Realistically speaking, even a value for n of 399 is a very small problem for real-world cryptography. The inefficiency of this intuitive solution points out the need for using the more sophisticated computational approach provided by the authors of the RSA algorithm.
The third program extends and completes a small example that is presented in incomplete form by the original authors of the RSA algorithm. This program uses predetermined keys and a Java implementation to encrypt and decrypt a short message with a block size of 4 and n equal to 2773. This program introduces and explains the issue of message coding and decoding and uses a fairly restrictive character set consisting of the space character and the twenty-six upper-case alphabetic characters.
The fourth program is more general and includes the ability to compute and apply the encryption keys for a character set that includes ninety-five of the most commonly used text characters. The version of the program that I will explain is purposely limited to a block size and key length of six characters.
This program uses a Java implementation of the algorithm provided by the original authors of the RSA algorithm for the computation of the keys e and d and for the common divisor n. This program is suitable for experimenting with different block sizes, different divisors, different values for the keys, etc. The next lesson in this series will extend the fourth program to support the concept of digital signatures. ## Discussion and Sample Code
The purpose of the program named
Most people who work in a technical field know how to solve for the unknowns in a set of three simultaneous equations with three unknowns. There are several ways to do this. Many of those people are familiar with a solution involving matrix inversion commonly referred to as the use of determinants.
Once a person understands that you can solve three simultaneous equations using matrix inversion, it's not much of a stretch for the same person to also understand that you can also solve much larger sets of simultaneous equations using matrix inversion. Thus, that person has an intuitive knowledge of how to solve for the unknowns in large sets of simultaneous equations involving many more unknowns.
However, there is a very large difference between having an intuitive knowledge of how to solve a set of fifty simultaneous equations using matrix inversion and actually doing it. Inverting the 3x3 matrix required to solve the small problem is much different from inverting the 50x50 matrix required to solve the larger problem. The 3x3 matrix can be inverted using pencil, paper, and a procedure that most of us learned in high school. Inverting the 50x50 matrix requires more sophisticated tools. In all probability, that person will need to consult a textbook or other reputable source to learn how to invert large matrices. In addition, even though the person may learn to implement the algorithm to invert the larger matrix, without a great deal of study, it is unlikely that the person will ever really understand why it work the way that it does.
The important point is, even though that person may never fully understand how the algorithm for inverting the large matrix works, the fact that the person has developed an intuitive knowledge of how to solve the small problem using matrix inversion causes the person to also have an intuitive knowledge of how to solve the larger problem. The large-matrix inversion algorithm is nothing more than a tool to help the person achieve a solution for a problem for which he already has an intuitive understanding.
Unless you have a penchant for advanced mathematics, you may never truly understand how the RSA algorithm, as presented by the original authors, actually works, particularly with respect to the creation of the keys and the divisor. However, my hope is to give you an intuitive understanding of how the RSA algorithm works based on the first two programs. The first program explains the algorithm using an approach that should be understandable by anyone having a fundamental knowledge of Java program. This program is clearly limited to the solution of small problems due to arithmetic overflow issues.
The second program extends the first program by using a particular Java class
named
Once you gain the intuitive understanding of how the RSA algorithm works, you can move on to the third and fourth programs, which use the original authors' procedure for creating keys and divisors. You can think of this procedure much the same way that you think of a large-matrix inversion program; simply as a tool for solving a large problem in a reasonable amount of time
As is usually the case, I will discuss and explain these programs in fragments. Complete listings of all four programs are presented in Listing 45 through Listing 48 near the end of the lesson.
Before getting into the code for the program, the screen output produced by
the program is shown in Figure 1.
I will refer back to this figure while discussing the behavior of this program.
The most fundamental concept in the RSA algorithm is shown in Figure 2.
As you can see, the encryption and decryption transformations are not
computationally difficult. In fact, they are especially easy using the
The difficult part is determining the correct values for e, d, and n for
message values and key lengths on the order of 100 digits. The first program
named
This program provides a very simple and intuitive solution of the RSA encryption algorithm. The program uses iteration along with trial-and-error to determine all of the non-duplicate values for e and d that can be used in combination to encrypt and decrypt message values ranging from 0 through n-1 inclusive when n has a value of 14. Both e and d are constrained to have values of 13 or less.
Referring back to the screen output shown in Figure 1, you will note that the four allowable combinations for e and d occur as two reciprocal pairs. This confirms that either key can be used to encrypt with the other key being use to decrypt. Note that this program purposely excludes from the output all combinations of d and e for which d equals e. The program was tested using SDK 1.4.2 under WinXP.
The controlling class and the
The code in Listing 1 simply declares variables that will be used later, and populates some of them. In particular, the value for n is set to 14 and remains at that value throughout the execution of the program.
Listing 2 displays the setup information shown at the top of Figure 1.
Listing 3 shows the beginning of a structure of three nested loops that
try all combinations of m, d, and e Those combinations of d and e that satisfy the conditions for every value of m are retained. All other combinations are discarded. In addition, combinations that satisfy the conditions but for which d is equal to e are also discarded.
Listing 3 shows the beginnings of the loops for m and e. There is no need to begin the outer loop with m equal to 0. The algorithm will always produce an output of 0 for a message value of 0. We aren't interested in values of either 0 or 1 for e. Raising any non-zero message value to a power of 0 produces 1. Raising a message value to a power of 1 produces the message value, which is not very interesting from an encryption viewpoint. If a message were encrypted using a value of 1 for e, the encrypted message would look just like the unencrypted message. Things get more interesting in the third line of Listing 3. This line
invokes the method named
The
The When the loop terminates normally, indicating that
This method can be used to execute either of the formulas shown in Figure 2. If the input parameters are m, e, and n, the method encrypts the message value into a cipher value. If the inputs are c, d, and n, the method decrypts a cipher value into a message value.
Returning to the code in the
The purpose of this loop is to test all possible values of d in the specified
range to see if a given value of d, along with the current values of e and m The code in Listing 5 invokes the
The values of e and d that are valid encryption and decryption keys for all values of m are obtained through a process of elimination. This process needs to begin with a list containing all possible combinations of d and e within the specified ranges for d and e. As it turns out, this list can be produced by processing a message value of 1. The value 1 raised to any power is 1. The value 1 modulus n is also 1. Therefore, all combinations of d and e will successfully encrypt and decrypt a message value of 1.
The code in Listing 6 is the beginning of a pair of nested
However, if x is equal to m, then a test is performed to determine if this
test was performed on a message value of 1. If so, the values for d
and e are encoded into a String and added to a
Listing 7 shows the
The code in Listing 7 saves only those combinations of d and e that successfully encrypt and decrypt this value of m.
The successful combinations are stored in a
The contents of this Listing 7 also signals the end of the
At this point, control is still within the outer If the value of m is greater than 1, the code in Listing 8 invokes the method
named
The code in Listing 8 also instantiates a new empty Listing 8 also signals the end of the
outer loop on m. If all values of m have been processed, control will
transfer to Listing 10, which will display the remaining combinations of d and e
in the
This method, which is shown in Listing 9, performs a logical
The code in Listing 9 is straightforward, and the comments should make the code self explanatory. Therefore, I won't discuss that code further.
Returning now to the discussion of
Once again, the code in Listing 10 is straightforward so I won't discuss it further. Listing 10 also signals the end of the
If you decide to run this program for different values of n, you should note that there is no valid solution for some values of n. In that case, the list of allowable keys presented by the program will simply be blank. I have also noticed that for some values of n, the code that checks for
potential arithmetic overflow throws an Rsa08 instead of Rsa07.
The output produced by the program named
As you can see, this output is considerably different from the output
produced by the program named
Perhaps the biggest difference is the increase in the number of allowable key combinations in Figure 3 as compared to Figure 1. For the set of parameters shown in Figure 3, there are 38 allowable key combinations as compared to only two for the parameters in Figure 1. This increase derives solely from the increased value for n and the increased range for m, e, and d.
The computational structure of the two programs is the same. However,
Rsa07.In theory, you could run this program for as large a value of n as you may desire. However, if you use a very large value of n, the program will require an exceptionally long time to produce a solution. Therefore, using this program for large values of n is not practical.
As with the program named
The primary difference between this program and the program named As I mentioned in the discussion for
Here is part of what Sun has to say about the
Some of the extra methods mentioned by Sun in the above quotation are exactly
what the doctor ordered for the type of programming being done here.
The conversion of the program named Because the control structure of this program, which you will find in Listing
46 near the end of the lesson, is essentially the same as the control structure of
I will begin with the declaration of variables and the population of some of
those variables in
A couple of things are worthy of note in Listing 11. First, For example, to initialize the variable named n in Listing 11, it was
necessary to instantiate a new
object of the Further, when the object was instantiated, it was initialized using an integer
value of 77 expressed as a
As a practical matter, the input
and output to
In case you are unfamiliar with the term
Many of the operations in this program involve adding or subtracting a value
of 1 from a
Listing 12 illustrates the use of the
The first statement in Listing 12 simply displays the value encapsulated in
the The remaining three statements in Listing 12 subtract a value of 1 from the
Listing 13 illustrates the use of the methods of the
The ability to perform relational operations on
This is the syntax used in the conditional clauses in the
If you do a side-by-side comparison of the code for
Once again, if you decide to experiment with different values for n, you
should use the program named
As explained earlier, this program extends and completes a small example that is presented in incomplete form by the original authors of the RSA algorithm. This program uses predetermined keys and a Java implementation to encrypt and decrypt a short message with a block size of 4 and n equal to 2773. This program introduces and explains the issue of message coding and decoding and uses a fairly restrictive character set consisting of the space character and the twenty-six upper-case alphabetic characters.
A complete listing of this program is shown in Listing 47 near the end of the lesson. The program was tested using Sun's Java SDK 1.4.2 under WinXP, producing the output shown in Figure 4.
Up to this point in this lesson, I haven't discussed anything about the text of the message being encrypted and decrypted. The RSA encryption algorithm is described in Figure 2, and is based solely on the use of a numeric input to produce a numeric output. Therefore, to make use of the RSA algorithm, you must devise a way to encode the text of your message into numeric form before encryption. You must then decode the numeric output from the decryption process using a reverse methodology to produce the original text of the message.
Now that I have mentioned the block size, I need to provide some background information to explain what I mean. Here is a little of what Wikipedia has to say on the subject:
You can follow the links in the above quotation to learn more about the two types of ciphers.
As I understand it, the RSA algorithm must be implemented as a block cipher if the original
message is of any significant length. As mentioned above, the original text message
must be encoded
into a string of digits. In my implementation, the string of digits is
subdivided into equal length segments of length One such
segment forms the message segments produced by subdividing the encoded message
into blocks.
The value of the blockSize.
In addition, the value of n must be larger than the largest possible value of
any message m shown in Figure 2.
The encoding scheme for
The The program uses the predetermined values for n, d, and e shown near the top of Figure 4. The theoretical basis for this program as well as a description of the
example encryption problem are provided by the original authors of
the RSA algorithm at:
http://theory.lcs.mit.edu/~rivest/rsapaper.pdf
The code fragment shown in Listing 14 shows the beginning of the class and
the beginning of the
The first five statements in Listing 14 establish predetermined values
from the original author's website encapsulated in The sixth statement in Listing 14 establishes a
The first four statements in Listing 15 declare some strings that will be populated later by the program. The next five statements display the values shown in the first five lines of text in the output shown in Figure 4.
The final statement in Listing 15 instantiates an object of the class
and stores its reference in the reference variable named
For a Because 38 is not evenly divisible by the
The code in Listing 16 appends a space
character onto the end of the
The code in Listing 16 also displays the extended
Listing 17 invokes the
Setting the
The purpose of the - space = 00
- A = 01
- B = 02
- C = 03
- ...
- Z = 26
The code in Listing 18 implements a simple substitution approach and
shouldn't require further explanation. The
Listing 19 invokes the
The This method can be used to encrypt or to decrypt the input string depending on whether the exponent is an encryption key or a decryption key. The method is hard coded to apply the algorithm for a fixed block size of four characters. Thus, this is not a general-purpose RSA method that can be applied for different block sizes.
Once again setting the
The code in Listing 20 declares and initializes some variables that will be used later.
Listing 21 shows the beginning of a
The code in Listing 21 gets the next block of four characters and uses them
to initialize a new
At this point, the value encapsulated in the
Referring back to Figure 2, the next step is to invoke the - Raise the value encapsulated in the object
referred to by
**block**to the power**exp**and to - Compute the modulus
using the divisor n, saving the remainder in the
**BigInteger**object referred to by**output**
This is shown in Listing 22.
This is one of the methods of the
For this case, the message substring encapsulated by
For our purposes, we need to convert the remainder to a four-character string inserting leading zeros if necessary. This is accomplished in a somewhat brute force manner shown in Listing 23.
Finally, the statement at the bottom of the
When all of the four-character blocks in the input string have been
processed, the
When the incoming string is the encoded text message and the incoming
parameter named
When the incoming string is the cipher text and the incoming parameter named
Returning now to the
Listing 25 displays the result in the thirteenth line in Figure 4. As mentioned earlier, this line of text matches the ninth line of text in Figure 4 which is the encoded message text prior to encryption.
Finally, Listing 26 invokes the
The
IMPORTANT: THIS PROGRAM IS DESIGNED SPECIFICALLY FOR INSTRUCTIONAL PURPOSES. IT WILL NOT EXECUTE PROPERLY FOR BLOCK SIZES AND KEYS GREATER THAN 6 CHARACTERS IN LENGTH. This program is a significant update to The encoding and decoding approach used in this program supports the 95 ASCII characters between space and tilde (~) inclusive.
This program uses the RSA algorithm along with the computed keys and common
divisor to encrypt and decrypt a message containing 23 characters using a block
size of 4 producing the output shown in Figure 5.
You can experiment with different block sizes by changing the value of the
variable named You can experiment with different encryption and decryption keys as well as a different common divisor by changing the value of the variable named e and recompiling. You can also produce a different decryption key k and a different common divisor n by changing the initial value of p and recompiling.
See the theoretical basis for RSA at: http://theory.lcs.mit.edu/~rivest/rsapaper.pdf Another good reference is at: http://www.math.mtu.edu/mathlab/COURSES/holt/dnt/phi4.html
Note that you can reverse the use of the two keys for encryption and decryption and get the same results. In other words, it doesn't matter which key you use to encrypt the message into cipher text as long as you use the other key to decrypt the cipher text.
In order for this algorithm to work correctly, it is necessary for the value of n to be greater than the maximum value of an encoded data block. It is also necessary for the number of characters in the value of n to be less than or equal to the block size. If the program is unable to satisfy both conditions simultaneously, it terminates with an error message.
This program was tested using SDK 1.4.2 and WinXP. The program produces the output shown in Figure 5.
The controlling class for the program named
Listing 27 defines a
The
The code in Listing 28 is straightforward. It does the following: - Instantiates an object of the class
**Params**in which to store the parameters. - Creates a test message string containing characters from the full range of the 95 characters supported by the encoding method.
- Declares some variables to be populated later by the program.
- Sets the block size and makes certain that it is divisible by 2.
- Gets and saves the maximum value of an encoded string for the specified block size and the encoding format used. For example, for a block size of 4, the maximum value would be 9494.
If you visit the theoretical basis published by the original authors of the RSA algorithm, you will see that the process of computing the keys requires the product of two prime numbers, p and q, whose product, n, must be greater than the largest possible value of a data block.
Listing 29 computes an initial value for p. There is nothing special about the approach used to get the initial value in Listing 29. In fact, it might be preferable to use a random number generator to produce this initial value. The final value for p will be a prime number close to this value.
Listing 29 also instantiates an object of the class and saves its reference
in the reference variable named
Listing 30 invokes the
The I will make no attempt in this lesson to explain how and why this algorithm works for producing e, d, and n. Rather, I will simply walk you through the code that implements the steps described by the authors.
Putting the The method begins by instantiating a
Then the - n = p*q > max
- The number of characters in n is <= blockSize
The first task is to get a prime number close to the initial value for p produced in Listing 29. The method uses this incoming initial value for p and then iterates by increasing the value of p until a highly-probable prime number is found.
As far as I can tell, there is no method to determine with absolute certainty
whether or not the value of a
This is the method used in the loop in Listing 31 to get a probable prime number for p that is close to the initial value for p.
The next step is to get a prime number for q that satisfies the two conditions listed earlier. This process begins in Listing 32.
Listing 32 makes a first guess for the value of q as being one less than the current prime value of p. This value will be modified through iteration until a value is found that satisfies the conditions listed earlier, or it is concluded that those conditions cannot be satisfied.
Without regard for whether or not q is prime, Listing 33 gets a value for q for which the number of digits in the product p*q doesn't exceed the block size. This is done by successively halving the value for q until the condition is satisfied. Then Listing 33 divides the value of q by 2 one more time to allow some room for incrementing the value of q later.
The current value of q satisfies one of the two required conditions, but may not be a prime number. Listing 34 gets the next prime number that is smaller than the current value of q.
Now we have prime values for p and q such that the number of characters in p*q is less than or equal to the block size. Next we need to confirm that the product of p and q is greater than the maximum possible value for a data block. This accomplished in Listing 35 by successively increasing the value of q by 1 until the condition is met.
Listing 36 confirms that both conditions are still being met. If not, the program terminates with an error message.
There are three more steps required to compute e, d, and n as described in
Figure 2. The next step is to compute a value referred to by the original
authors as phi This computation is straightforward as shown in Listing 37.
The next step is to find a value for e such that the greatest common
denominator of e and phi is equal to 1. This is accomplished using the
The
The final step is to compute the value of d using the
Listing 39 also signals the end of the The purpose of these three final steps in the Alternatively, you can take it on faith that they successfully developed a
mathematical solution to the same problem that we solved using brute force trial
and error iteration in the programs named
The first six lines of text in Figure 5 show the values produced by the
invocation of the
Returning to the
In this case, I purposely extended the message with dashes so that the extension would be visible in the screen output. Listing 40 also displays the extended message as shown in Figure 5.
Listing 41 encodes the plain text into numeric format to prepare it for encryption using the RSA algorithm and displays the encoded result in Figure 5.
The The purpose of this version of the - space = 00
- A = 33
- ...
- Z = 58
- ...
- a = 65
- ...
- ~ = 94
The code used to accomplish this is straightforward and won't be discussed in detail. You can view that code in Listing 48 near the end of the lesson.
Listing 42 invokes the Note that this invocation of the method receives the encryption key e an incoming parameter.
This version of the Because of the similarity of the two versions, I won't discuss this version in detail. You can view the method in Listing 48 near the end of the lesson.
doRSA method again, passing the
decryption key d as a parameter to decrypt the encrypted message.
Listing 43 also displays the decrypted message as the fourteenth line of output in Figure 5. Note that the decrypted message exactly matches the encoded text in the tenth line in Figure 5 as would be expected.
decode method to transform the message from
numeric format back to plain text. Listing 44 also displays the resulting
text as the last line in Figure 5. As you can see, the result is an exact
match for the extended plain text message shown in the eighth line of Figure 5.
Listing 44 also signals the end of the
decode method simply reverses the transformation performed by the
encode method discussed earlier. The code in the decode method
is straightforward and doesn't merit a detailed discussion here. You can
view the decode method in its entirety in Listing 48 near the end of the
lesson.## Run the ProgramsI encourage you to copy, compile and run the following programs that are provided in this lesson: - Rsa07
- Rsa08
- Rsa01
- Rsa03
Experiment with the programs, making changes and observing the results of your changes. Above all, have fun and use these programs to learn as much as you can about the theory behind and the mechanics of public key cryptography as implemented using Java. ## SummaryIn this lesson, I explained the general philosophy of public key cryptography. I also provided four sample programs that illustrate various aspects of public key cryptography through the use of the RSA algorithm. The first two programs were designed to give you an intuitive understanding of the RSA algorithm. The third program provides a Java implementation of a small example that is presented in incomplete form by the RSA algorithm's authors. The fourth program is a more general implementation of the RSA algorithm. ## What's Next?The next lesson in this series will explain the use of public key cryptography for the creation and use of digital signatures for the signing of messages. Future lessons will explain the use of symmetric key cryptography using Java. ## Complete Program ListingsComplete listings of the programs discussed in this lesson are provided in Listing 45 through Listing 48 below.
The programs that I am providing and explaining in this series of lessons are
not intended to be used for production cryptography. If you need to do
cryptography using Java, you should use
Sun's Java Cryptography Extension The programs that I am providing were developed solely for instructional purposes. They are intended to help you to experiment with and to learn about various cryptographic algorithms and to gain a better understanding of how they work, and why they do what they do.
Copyright 2004, Richard G. Baldwin. Reproduction in whole or in part in any form or medium without express written permission from Richard Baldwin is prohibited. ## About the author
Richard Baldwin
is a college professor (at Austin Community College in Austin, TX) and
private consultant whose primary focus is a combination of Java, C#, and
XML. In addition to the many platform and/or language independent benefits
of Java and C# applications, he believes that a combination of Java, C#,
and XML will become the primary driving force in the delivery of structured
information on the Web.
-end- |