Final Project Skeleton/CipherClient.javaFinal Project Skeleton/CipherClient.javaimport java.io.*;
import java.net.*;
import java.security.*;
import javax.crypto.*;
publicclassCipherClient
{
publicstaticvoid main(String[] args)throwsException
{
String message ="The quick brown fox jumps over the lazy dog.";
String host ="paradox.sis.pitt.edu";
int port =7999;
Socket s =newSocket(host, port);
// YOU NEED TO DO THESE STEPS:
// -Generate a DES key.
// -Store it in a file.
// -Use the key to encrypt the message above and send it over socket s to the server.
}
}
Final Project Skeleton/CipherServer.javaFinal Project Skeleton/CipherServer.javaimport java.io.*;
import java.net.*;
import java.security.*;
import javax.crypto.*;
publicclassCipherServer
{
publicstaticvoid main(String[] args)throwsException
{
int port =7999;
ServerSocket server =newServerSocket(port);
Socket s = server.accept();
// YOU NEED TO DO THESE STEPS:
// -Read the key from the file generated by the client.
// -Use the key to decrypt the incoming message from socket s.
// -Print out the decrypt String to see if it matches the orignal message.
}
}
Final Project Skeleton/ElGamalAlice.javaFinal Project Skeleton/ElGamalAlice.javaimport java.io.*;
import java.net.*;
import java.security.*;
import java.math.BigInteger;
publicclassElGamalAlice
{
privatestaticBigInteger computeY(BigInteger p,BigInteger g,BigInteger d)
{
// IMPLEMENT THIS FUNCTION;
}
privatestaticBigInteger computeK(BigInteger p)
{
// IMPLEMENT THIS FUNCTION;
}
privatestaticBigInteger computeA(BigInteger p,BigInteger g,BigInteger k)
{
// IMPLEMENT THIS FUNCTION;
}
privatestaticBigInteger computeB(String message,BigInteger d,BigInteger a,BigInteger k,BigInteger p)
{
// IMPLEMENT THIS FUNCTION;
}
publicstaticvoid main(String[] args)throwsException
{
String message ="The quick brown fox jumps over the lazy dog.";
String host ="paradox.sis.pitt.edu";
int port =7999;
Socket s =newSocket(host, port);
ObjectOutputStream os =newObjectOutputStream(s.getOutputStream());
// You should consult BigInteger class in Java API documentation to find out what it is.
BigInteger y, g, p;// public key
BigInteger d;// private key
int mStrength =1024;// key bit length
SecureRandom mSecureRandom =newSecureRandom();// a cryptographically strong pseudo-random number
// Create a BigInterger with mStrength bit length that is highly likely to be prime.
// (The '16' determines the probability that p is prime. Refer to BigInteger documentation.)
p =newBigInteger(mStrength,16, mSecureRandom);
// Create a randomly generated BigInteger of length mStrength-1
g =newBigInteger(mStrength-1, mSecureRandom);
d =newBigInteger(mStrength-1, mSecureRandom);
y = computeY(p, g, d);
// At this point, you have both the public key and the private key. Now compute the signature.
BigInteger k = computeK(p);
BigInteger a = computeA(p, g, k);
BigInteger b = computeB(message, d, a, k, p);
// send public key
...
Final Project SkeletonCipherClient.javaFinal Project SkeletonC.docx
1. Final Project Skeleton/CipherClient.javaFinal Project
Skeleton/CipherClient.javaimport java.io.*;
import java.net.*;
import java.security.*;
import javax.crypto.*;
publicclassCipherClient
{
publicstaticvoid main(String[] args)throwsException
{
String message ="The quick brown fox jumps over the lazy dog.
";
String host ="paradox.sis.pitt.edu";
int port =7999;
Socket s =newSocket(host, port);
// YOU NEED TO DO THESE STEPS:
// -Generate a DES key.
// -Store it in a file.
// -
Use the key to encrypt the message above and send it over socke
t s to the server.
}
}
Final Project Skeleton/CipherServer.javaFinal Project
Skeleton/CipherServer.javaimport java.io.*;
import java.net.*;
import java.security.*;
import javax.crypto.*;
publicclassCipherServer
2. {
publicstaticvoid main(String[] args)throwsException
{
int port =7999;
ServerSocket server =newServerSocket(port);
Socket s = server.accept();
// YOU NEED TO DO THESE STEPS:
// -Read the key from the file generated by the client.
// -
Use the key to decrypt the incoming message from socket s.
// -
Print out the decrypt String to see if it matches the orignal mess
age.
}
}
Final Project Skeleton/ElGamalAlice.javaFinal Project
Skeleton/ElGamalAlice.javaimport java.io.*;
import java.net.*;
import java.security.*;
import java.math.BigInteger;
publicclassElGamalAlice
{
privatestaticBigInteger computeY(BigInteger p,BigInteger g,Big
Integer d)
{
// IMPLEMENT THIS FUNCTION;
}
privatestaticBigInteger computeK(BigInteger p)
{
// IMPLEMENT THIS FUNCTION;
}
3. privatestaticBigInteger computeA(BigInteger p,BigInteger g,Big
Integer k)
{
// IMPLEMENT THIS FUNCTION;
}
privatestaticBigInteger computeB(String message,BigInteger d,
BigInteger a,BigInteger k,BigInteger p)
{
// IMPLEMENT THIS FUNCTION;
}
publicstaticvoid main(String[] args)throwsException
{
String message ="The quick brown fox jumps over the lazy dog.
";
String host ="paradox.sis.pitt.edu";
int port =7999;
Socket s =newSocket(host, port);
ObjectOutputStream os =newObjectOutputStream(s.getOutputSt
ream());
// You should consult BigInteger class in Java API documentati
on to find out what it is.
BigInteger y, g, p;// public key
BigInteger d;// private key
int mStrength =1024;// key bit length
SecureRandom mSecureRandom =newSecureRandom();// a crypt
ographically strong pseudo-random number
// Create a BigInterger with mStrength bit length that is highly l
ikely to be prime.
// (The '16' determines the probability that p is prime. Refer to
4. BigInteger documentation.)
p =newBigInteger(mStrength,16, mSecureRandom);
// Create a randomly generated BigInteger of length mStrength-
1
g =newBigInteger(mStrength-1, mSecureRandom);
d =newBigInteger(mStrength-1, mSecureRandom);
y = computeY(p, g, d);
// At this point, you have both the public key and the private ke
y. Now compute the signature.
BigInteger k = computeK(p);
BigInteger a = computeA(p, g, k);
BigInteger b = computeB(message, d, a, k, p);
// send public key
os.writeObject(y);
os.writeObject(g);
os.writeObject(p);
// send message
os.writeObject(message);
// send signature
os.writeObject(a);
os.writeObject(b);
s.close();
}
}
Final Project Skeleton/ElGamalBob.javaFinal Project
Skeleton/ElGamalBob.javaimport java.io.*;
5. import java.net.*;
import java.security.*;
import java.math.BigInteger;
publicclassElGamalBob
{
privatestaticboolean verifySignature(BigInteger y,BigInteger g,
BigInteger p,BigInteger a,BigInteger b,String message)
{
// IMPLEMENT THIS FUNCTION;
}
publicstaticvoid main(String[] args)throwsException
{
int port =7999;
ServerSocket s =newServerSocket(port);
Socket client = s.accept();
ObjectInputStream is =newObjectInputStream(client.getInputStr
eam());
// read public key
BigInteger y =(BigInteger)is.readObject();
BigInteger g =(BigInteger)is.readObject();
BigInteger p =(BigInteger)is.readObject();
// read message
String message =(String)is.readObject();
// read signature
BigInteger a =(BigInteger)is.readObject();
BigInteger b =(BigInteger)is.readObject();
boolean result = verifySignature(y, g, p, a, b, message);
System.out.println(message);
6. if(result ==true)
System.out.println("Signature verified.");
else
System.out.println("Signature verification failed.");
s.close();
}
}
Final Project Skeleton/ProtectedClient.javaFinal Project
Skeleton/ProtectedClient.javaimport java.io.*;
import java.net.*;
import java.security.*;
import java.util.Date;
publicclassProtectedClient
{
publicvoid sendAuthentication(String user,String password,Out
putStream outStream)throwsIOException,NoSuchAlgorithmExce
ption
{
DataOutputStream out =newDataOutputStream(outStream);
// IMPLEMENT THIS FUNCTION.
out.flush();
}
publicstaticvoid main(String[] args)throwsException
{
String host ="cse.unt.edu";
int port =7999;
String user ="George";
String password ="abc123";
Socket s =newSocket(host, port);
7. ProtectedClient client =newProtectedClient();
client.sendAuthentication(user, password, s.getOutputStre
am());
s.close();
}
}
Final Project Skeleton/ProtectedServer.javaFinal Project
Skeleton/ProtectedServer.javaimport java.io.*;
import java.net.*;
import java.security.*;
publicclassProtectedServer
{
publicboolean authenticate(InputStream inStream)throwsIOExce
ption,NoSuchAlgorithmException
{
DataInputStream in =newDataInputStream(inStream);
// IMPLEMENT THIS FUNCTION.
}
protectedString lookupPassword(String user){return"abc123";}
publicstaticvoid main(String[] args)throwsException
{
int port =7999;
ServerSocket s =newServerSocket(port);
Socket client = s.accept();
ProtectedServer server =newProtectedServer();
if(server.authenticate(client.getInputStream()))
9. md.update(mush);
md.update(makeBytes(t2, q2));
return md.digest();
}
publicstaticbyte[] makeDigest(String user,String password,
long t1,double q1)
throwsNoSuchAlgorithmException
{
// IMPLEMENT THIS FUNCTION.
}
}
Project Hints
Double Password Authentication
Few things to keep in mind in this exercise (mainly with regards
to
DataInputStream/DataOutputStream class:
[e.g., out.writeUTF(x)]
Doubles (readInt,
readDouble)
use write. Here you will
need to worry about passing the length information for each
value you pass - it may be
tedious
10. use write. When you use
write to pass a byte array, reading the same array at the server
requires you to also know
the size of the byte array. So before you pass the digest value,
you could pass the length
of the byte array that stores the digest value (using writeInt)
and then the digest itself. At
the other end you can read the length value (using readInt) and
then use that to create the
byte array that can be used to store the appropriate size of bytes
read from the input
stream. Here is a sample you could do for the digest value
passed.
Client Server
out.writeInt(digestValue.length);
out.write(digestValue);
out.flush();
//digestValue is of type byte[]
int length = in.readInt();
byte[] protected = new
byte[length];
in.readFully(protected);
//reads the number of
bytes equal to length of
protected
time value, etc.) and the digest.
At the server you have to re-compute the digest the same way
11. you computed the at the
client side using the original values. Then, you need to compare
the digest value received
from the client with the newly computed digest. Here is one way
you can check if the two
digests are equal:
MessageDigest.isEqual(recomputedDigest, receivedDigest);
ElGamal Signature
Keys
- both less than p
ate key is d, public key is (y, g, p)
Signing message m
-1)
-da)*k-1) mod (p-1)
Where k-1 is computed as follows: k-1 =k.modInverse(p-1).
Verifying the signature
(y^a).(a^b) mod p = g^m mod p
Note "(y^a).(a^b) mod p" is equivalent to "[(y^a) mod p] [(a^b)
12. mod p] mod p"
Some issues
- be careful. For
instance, to calculate (p-1)
(call it pMinusOne), you could do the following
BigInteger pOne = BigInteger.valueOf(1);
BigInteger pMinusOne = p.substract(pOne) // where p is the
random number
-1)
loop {
BigInteger k = new BigInterger (???); // check existing code of
this type
} until k is relatively prime to (p-1)
To check "BigInteger k is relatively prime to BigInteger p" you
can do the following:
k.gcd(pMinusOne).equals(pOne) == true;
Cipher
Three things to do here.
1. Generating DES Key
13. examples regarding how to
create one. Some Classes that you need to understand are
Key and KeyGenerator
ck out getInstance(??), init(new SecureRandom()) and
generateKey()
functions of class KeyGenerator.
2. Storing keys in a file
ObjectOutputStream out = new ObjectOutputStream(new
FileOutputStream("KeyFile.xx"));
That is, you create an object output stream to an output file
name KeyFile.xx.
Since it is an object output stream you can now write the Key
object that has your key. Assuming
you have
Key k = .... // creates the key using the KeyGenerator object
that is using some instance of
encryption algorithm, DES here.
out.writeObject(k); // will store your key object in the file.
At the server, you can now do:
Key k = (Key) in.readObject(); // to read from object in which is
an ObjectInputStream
communicate to the server. However,
14. instead of a file (through FileOutputStream), you now need to
associate the socket ( it is
given) with the ObjectOutputStream object. If s is the Socket
object you have created
then you can do the following:
ObjectOutputStream outSocket = new
ObjectOutputStream(s.getOutputStream());
channel to another machine
by associating with it a port and the host address.
2. Cipher - Encrypting and Decrypting and then outputting the
digest
algorithm you can do the
following.
Cipher cipher =
Cipher.getInstance("DES/ECB/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, k);
This sets the cipher object to Encrypt mode with the specified
key k (a Key object). You can do
the same two statements in the server to initialize a cipher
object to Cipher.DECRYPT_MODE
m
(CipherInputStream in server)
Note that in the documentation at the URL provided to you sey
15. the following about the
CipherOutputStream class:
A CipherOutputStream is composed of an OutputStream and a
Cipher so that write() methods
first process the data before writing them out to the underlying
OutputStream. The cipher must
be fully initialized before being used by a CipherOutputStream.
For example, if the cipher is initialized for encryption, the
CipherOutputStream will attempt to
encrypt data before writing out the encrypted data.
Hence, you can create a CipherOutputStream object to pass the
encrypted value to the server.
You can now easily create an CipherOutputStream object:
CipherOutputStream cipherOut = new
CipherOutputStream(sSocket, cipher);
Now you can use cipherOut.write(byte []) to send the message
encrypted using DES to the server
- as cipherOut is now associated with sSocket object. Note that
the input to the write function is a
byte stream so if you have a String message you need to get the
bytes.
= .." (similar to
CipherInputStream) and then use cipherIn.read() to read the
message bytes.
16. CSCE 4550/ 5550 Introduction to Computer Security
Final Project
Total Points: 150
Due Date: Dec 6, 2013
1. Message Digest [25 Points]
Write a program to demonstrate the use of hashing using MD5
and SHA scheme and the
MessageDigest class.
Your program should allow a user to enter a string; the program
then hashes it and output
the result.
You will need to consult Java API documentation to learn how
to use java classes. You
can download and install the documentation yourself, or you can
access them from this
URL: http://java.sun.com/j2se/1.4.2/docs/api/index.html
2. Various Crypto Techniques [125 Points]
The objective of this exercise is to use Java features to write
some security mechanisms
that can be used in applications. You will be using the classes
from Java Cryptographic
Extension to implement them.
You will need to consult Java API documentation. You can
download and install the
17. documentation yourself, or you can access them from this URL:
http://java.sun.com/j2se/1.4.2/docs/api/index.html
Java books that you can reference
Inside Java 2 Platform Security, 2nd Edition, L. Gong, G.
Ellision, M. Dageforde
Java Security, Scott Oaks, O’Reilly
For each part of the assignment, skeleton Java code has been
provided. These skeletons
will NOT compile. You will need to make modifications on
them before they can be
successfully compiled and run.
A) Authentication
For the first part of the assignment, you should use the skeleton
Java code to implement
double-strength password login using message digest. The
following diagram illustrates
the double strength password.
Note that you need to generate 2 random numbers and 2
timestamps.
There are three classes defined:
18. makeDigest (version 1),
and makeDigest (version 2).
o makeBytes takes in a long integer and a double, then converts
them into a
single byte array. makeBytes has already been implemented for
you.
o makeDigest (version 1) takes in a byte array, a timestamp, and
a random
number, then generates a digest using SHA. This function has
already
been implemented for you.
o makeDigest (version 2) takes in a user name, a password, a
timestamp, and
a random number, then generates a digest using SHA. You need
to
implement this function. You may have to consult
MessageDigest API in
the documentation.
functions: main and
sendAuthentication.
o main is the starting point of the client program and has
already been
implemented for you. Make sure the host variable is set to the
correct
server address (it is currently set to cse.unt.edu).
o sendAuthentication is the function that you need to
19. implement. It takes in
user name, password, and an output stream as the function
inputs. In this
function, you should implement double-strength password
authentication
and send to the server by writing to the variable ‘out’. Consult
DataOutputStream API on how to write different data types to
‘out’.
ts the server. There are
three functions: main,
lookupPassword, and authenticate.
o main is the starting point of the server program and has
already been
implemented for you. It creates a server process that waits for
an
incoming connection. Once a connection is established,
authenticate is
called to authenticate the user. If the user successfully
authenticate, your
program should print out “Client logged in.”
o lookupPassword, which simply returns the password of the
user stored on
the server.
o authenticate is the function which you need to implement to
authenticate
the user trying to log in. Consult DataInputStream API on how
to read
data from the ‘in’ stream. The function should return either true
20. or false
depending on whether the user is authenticated.
B) Signature
In this part of the assignment, you are to implement the
ElGamal Signature scheme
described below.
The ElGamal Signature scheme is similar to the Diffie-Hellman
scheme. It relies on the
difficulty of solving the discrete logarithm problem. Choose a
prime p and two random
numbers g and d both less than p. Compute y = gd mod p. The
public key is the triplet (y,
g, p); the private key is d.
Suppose Alice wants to send Bob a signed contract m. She
chooses a number k that is
relatively prime to p – 1 and has not been used before. She
computes a = mk mod p and
then uses the Extended Euclidean Algorithm to find b such that
m = (da + kb) mod p – 1
The pair (a, b) is the signature.
To verify the signature, check that yaab mod p = gm mod p
EXAMPLE: Alice and Bob decide to use the El Gamal digital
signature scheme. Alice
chooses p = 29, g = 3, and dAlice = 6, yielding y = 4. She wants
to send Bob the signed
contract X (23). She chooses k = 5, which is relatively prime to
28. She computes
21. a = 35 mod 29 = 11
and then uses the Extended Euclidean Algorithm to solve for b:
23 = (6 x 11 + 5 x b) mod 28
This yields b = 25. She sends Bob the message m = 23 and the
signature (11, 25).
Bob obtains the message and wants to verify the signature. He
computes
yaab mod p = 4111125 mod 29 = 8
and
gm mod p = 323 mod 29 = 8
Because the two match, Alice signed the message.
If someone learns k, the corresponding message m, and the
signature (a, b), then she can
use the Extended Euclidean Algorithm to recover x, Alice's
public key.
EXAMPLE: Bob happens to learn that Alice signed the last
message using k = 5. He
immediately solves the following equation for d:
m = (da + kb) mod p – 1 →23 = (11d + 5 x 25) mod 28
which yields d = 6. This is Alice's private key.
22. There are two classes in this assignment, ElGamalAlice and
ElGamalBob, corresponding
to the sender (Alice) and the receiver (Bob). The main functions
for both the classes have
been written for you. Your assignment is to write various
functions that implement
ElGamal key generation and signature creation algorithms (for
Alice), and signature
verification algorithm (for Bob). The functions you have to
implement are indicated in
the source files.
C) Encryption
In this part of the assignment, the client program CipherClient
should (1) generate a DES
key and stores the key in a file, (2) encrypts the given String
object using that key and
sends the encrypted object over the socket to the server. The
server program
CipherServer then uses the key that was previously generated by
the client to decrypt the
incoming object. The server obtains the key simply by reading it
from the same file that
the client previously generated. The server should then print out
the decrypted message.
For this part of the assignment, you will need to consult
external sources and
documentations on how to generate a DES key, write to or read
from a file, and perform
encryption/decryption of an object.
Most of the needed information should be available at:
http://java.sun.com/products/jce/doc/guide/API_users_guide.ht
ml
23. D) Public-Key System
In this part of the assignment, you will need to demonstrate the
use of RSA Public-key
system to exchange messages that achieve confidentiality and
integrity/authentication as
well as the combination of both. You can assume a simple way
of sharing public keys
between the two communicating parties. You can reuse the basic
code provided for above
for this assignment.
E) X.509 certificates
In this part of the assignment, you will need to demonstrate the
use of X.509 certificate to
exchange messages that achieve confidentiality. The client
loads the server’s certificate
and proceeds to verify its authenticity and validity. This
includes checking the expiration
date and verifying if the certificate was signed using the private
key that corresponds to
the specified public key. Also, you need to print the content of
the certificate you
received. If the certificate received is valid, proceed to
exchange confidential messages
between the two parties. You can reuse the code previously
provided for part C.
You will need to create an X.509 certificate for the Server,
using RSA as the key
24. generation algorithm. This certificate can be self-signed and it
should have your name.
You can use keytool for this purpose. keytool is installed as part
of the standard Java
SDK/Runtime library, and is located in its bin subfolder. Refer
to the keytool’s
documentation for further instructions.
http://download.oracle.com/javase/1.5.0/docs/tooldocs/windows
/keytool.html
Finally, answer these questions in the report.
What are the limitations of using self-signed certificates? What
are they useful for?
Project Submission: Submit a single ZIP file with your UNT
email ID as its filename
via the Blackboard system. The package should contain all your
source files and a
readme file including the answers to the above questions. You
also need to demonstrate
your programs to the TA in person, where you may be asked to
explain about different
parts of your code. The date for demo will be announced later.