Sei sulla pagina 1di 26

Assignment 2 Network Software

template
Introduction
This software template will use java programming language as a means of demonstration of creating
a network program with ability to securely communication between server and clients in which files
transferred between will be encrypted and checked for integrity.

The communication between client and server will be performed using public key certification for
encryption.

Public-private keypair
Firstly, we will try to generate a random public encryption key pair. The function for public
encryption comes from Java Cryptography Extension (JCE).
TM

The key pair is generated by using KeyPairGenerator. In the sample program, I have create a tool
CipherGenerator for this specific purpose.

The CipherGenerator create a Jkeypair object which function is to create public and private key files.
Key files is then store in form of:

 Keyfile.publ for public key


 Keyfile.pri for private key

These key file will be sued for encryption latter on.

Pseudo code
The pseudo code for CipherGenerator are:

public class CipherGenerator {

public main(){

//main menu for function selection:

1. Generate public key pair files for encryption and session keys
//call keypairgenerate(String algorithm, int keySize, String output)
2. Encrypt a document
// call readKey(String algorithm, String mode, String input) for key value return.
//call cipherGenerator(String algorithm, String mode, Key ke, String input, String output)
with key value and encrypt mode for document encrypt
3. Decrypt a document
//call readKey(String algorithm, String mode, String input) for key value return.
//call cipherGenerator(String algorithm, String mode, Key ke, String input, String output)
with key value and decrypt mode for document decrypt

4. Return hash value


//call md5(String input) with file name as parameter to produce has key of the file

public void keypairgenerate(String algorithm, int keySize, String output){

//create Jkeypair object

//Generate Key pair files

public static Key readKey(String algorithm, String mode, String input){

//Mode is “encrypt” or “decrypt”

//Depend on mode, private (decrypt) or public (encrypt) key are return

public static void cipherGenerator(String algorithm, String mode, Key ke, String input, String
output){

// Mode is “encrypt” or “decrypt”

//Depend on mode, the String input (file name) document is decrypt or encrypt

public static String md5(String input){

// input file name and produce md5 hash value of the file.

Certificate
A digitally signed statement from the issuer saying that the public key of the subject has some
specific value. The certificate store public and private key that is needed for connection between
client and server in SSL. The certificate using in this project is X.509 Certificate format

The certificate using for connection is generated using keytool.exe from Java SDK. Procedure is to
follow command:

keytool -genkey -alias tuan_anh –keystore tuananh.jks


Client – Server
The 2 application that will be located on client and server respectably; each of them will have a copy
of CipherGenerator.java and Jkeypair.java which will provide them with function to encrypt and
decrypt of the data.

Client and Server communicate with each other through SSL connection.

Pseudo code
Server:
public static void main(String[] args){

//retrieve certificate key store and load certificate for SSL connection

// create SSL Socket

//provide function of server to retrieve public key, encrypt and send encrypted document, send
document hash to client

public static void sendHash(String file, BufferedWriter w, CipherGenerator cp){

//function to send hash key of a specific file to client

public static String selectFile(){

//Select file, return file name of the selected file.

public static void receiveFile( int filesize, int current, InputStream is, CipherGenerator cp){

//specific to retrieve public key from client

//receive input stream and write it down to file Keyfile-copy.publ

public static void sendEFile(OutputStream os){

//specific for sending encrypted document encrypted.txt to output stream

}
Client
public static void main(String[] args){

//retrieve certificate key store and load certificate for SSL connection

// connect to SSL Socket

//provide function of client to retrieve encrypted file, decrypt, retrieve hash value, and perform hash
check on the transferred document.

public static void hashCheck(String originalHash, String currentHash){

//perform hash check on file take in original and current hash value and compare. If not valid then
the file transfer is unsuccessful

public static String retreiveHash(BufferedReader r) throws Exception{

//retrieve hash value of the transferred file from server.

public static String selectFile(){

//Select file, return file name of the selected file.

public static void sendKey(String input, OutputStream os, CipherGenerator cp){

//specific for sending public key file

//read public key file and produce it to output stream

public static void receiveFile( int filesize, int current, InputStream is){

//specific to retrieve encrypted message from server

//receive input stream and write it down to file encrypted.txt

User document
Client.java provides the following function:

1. Send the public key file to server

2. Retreive and decrypt the encrypted document


3. Perform hash check of file transfer

Server.java provides the following function:

1. Retreive the public key from the client and encrypt a document file

2. Send the encrypted document to client

3. Send the hash value to client

Each option of Client and Server has to be selected respectably following:

1. Client selects sent public key to server (1) and specify the value of the public key file
name
2. Server selects retrieves the public key from the client (1) and specify the document need
to be encrypted (the encrypted document will be named “encrypted.txt”).
3. Server selects Send the encrypted document to client (2)
4. Client selects retrieving and decrypts the encrypted document (2). The decrypted
document will be named “decrypted.txt”
5. Server selects send has value of the sent document (3) to client (user must re-input the
file name)
6. Client select to perform hash check (3) to determine if the file transfer have success or
not (hash check will be perform for “decrypted.txt”).

Program code:
JKeyPair.java
package network;

import java.io.*;

import java.math.*;

import java.security.*;

import java.security.interfaces.*;

import javax.crypto.*;

import javax.crypto.spec.*;

class JKeyPair {

public void getKeysPairs(int keySize, String output, String algorithm) throws Exception {
KeyPairGenerator kg = KeyPairGenerator.getInstance(algorithm);

kg.initialize(keySize);

KeyPair pair = kg.generateKeyPair();

PrivateKey priKey = pair.getPrivate();

PublicKey pubKey = pair.getPublic();

String file = output+".pri";

FileOutputStream out = new FileOutputStream(file);

byte[] ke = priKey.getEncoded();

out.write(ke);

out.close();

file = output+".publ";

out = new FileOutputStream(file);

ke = pubKey.getEncoded();

out.write(ke);

out.close();

public void getSessionKey(int keySize, String output, String algorithm) throws


NoSuchAlgorithmException{

try {

KeyGenerator keg = KeyGenerator.getInstance(algorithm);

keg.init(keySize);

Key sk = keg.generateKey();

String file = output+".sess";

FileOutputStream out = new FileOutputStream(file);

byte[] ke = sk.getEncoded();

out.write(ke);

out.close();

}catch (Exception e) {
System.out.println("Exception: "+e);

return;

CipherGenerator.java
package network;

/**

* @author Tuan Anh Tran

*/

import javax.crypto.*;

import javax.crypto.spec.*;

import java.security.*;

import java.security.spec.*;

import java.io.*;

import java.util.Scanner;

import java.math.*;

public class CipherGenerator {

/**

* @param args the command line arguments

*/

public CipherGenerator(){

public static void main(String[] args) throws Exception{


Scanner input = new Scanner(System.in);

int keySize = 512;//Integer.parseInt(a[0]);

String output = "Keyfile";

String algorithm = "RSA"; // RSA, DSA

//String inFile = "a.txt";

//String outFile = "a2.txt";

String cfile = "a.txt";

Key ke = null;

//Option:

System.out.println("Please sellect the following option:");

System.out.println("1. Generate public key pair files for encryption and session keys");

System.out.println("2. Encrypt a document");

System.out.println("3. Decrypt a document");

System.out.println("4. Return hash value");

System.out.print("Your choice: ");

String temp = input.nextLine();

int choice = Integer.parseInt(temp);

switch (choice) {

case 1:

keypairgenerate(algorithm, keySize, output);

break;

case 2:

System.out.println("Please put your document to working directory and type it name");

String inFile = input.nextLine();

System.out.println("Please specify the encrypted message name");


String outFile = input.nextLine();

ke = readKey(algorithm, "encrypt", "Keyfile.publ");

cipherGenerator(algorithm, "encrypt", ke, inFile, outFile);

break;

case 3:

System.out.println("Please put your encrypted document to working directory and type it


name");

String enFile = input.nextLine();

System.out.println("Please specify the decrypted message name");

String deFile = input.nextLine();

ke = readKey(algorithm, "decrypt", "Keyfile.pri");

cipherGenerator(algorithm, "decrypt", ke, enFile, deFile);

break;

case 4:

String str=md5(cfile);

break;

default: System.out.println("Invalid Input");break;

public static void keypairgenerate(String algorithm, int keySize, String output) {

//int keySize = 512;//Integer.parseInt(a[0]);

//String output = "Keyfile";

//String algorithm = "RSA"; // RSA, DSA


try {

JKeyPair jkeypair = new JKeyPair();

jkeypair.getKeysPairs(keySize,output,algorithm);

jkeypair.getSessionKey(56, output, "DES");

System.out.println("Please check your working folder for key files!");

} catch (Exception e) {

System.out.println("Exception: "+e);

return;

public static Key readKey(String algorithm, String mode, String input) throws Exception {

KeyFactory keyFactory = KeyFactory.getInstance(algorithm);

System.out.println();

System.out.println("Key reading...");

FileInputStream fis = new FileInputStream(input);

int kl = fis.available();

byte[] kb = new byte[kl];

fis.read(kb);

fis.close();

Key ke = null;

if (mode.equalsIgnoreCase("encrypt")) {

X509EncodedKeySpec pubKeySpec

= new X509EncodedKeySpec(kb);

ke = keyFactory.generatePublic(pubKeySpec);
} else if (mode.equalsIgnoreCase("decrypt")) {

PKCS8EncodedKeySpec priKeySpec

= new PKCS8EncodedKeySpec(kb);

ke = keyFactory.generatePrivate(priKeySpec);

} else

throw new Exception("Invalid mode: "+mode);

System.out.println();

return ke;

public static void cipherGenerator(String algorithm, String mode, Key ke, String input, String
output) throws Exception {

Cipher cf = Cipher.getInstance(algorithm);

if (mode.equalsIgnoreCase("encrypt"))

cf.init(Cipher.ENCRYPT_MODE,ke);

else if (mode.equalsIgnoreCase("decrypt"))

cf.init(Cipher.DECRYPT_MODE,ke);

else

throw new Exception("Invalid mode: "+mode);

System.out.println();

FileInputStream fis = new FileInputStream(input);

FileOutputStream fos = new FileOutputStream(output);

int bufSize = 2048;

byte[] buf = new byte[bufSize];

int n = fis.read(buf,0,bufSize);

int fisSize = 0;
int fosSize = 0;

while (n!=-1) {

fisSize += n;

byte[] out = cf.update(buf,0,n);

fosSize += out.length;

fos.write(out);

n = fis.read(buf,0,bufSize);

byte[] out = cf.doFinal();

fosSize += out.length;

fos.write(out);

fis.close();

fos.close();

System.out.println();

System.out.println("Cipher Process Success!");

public static String md5(String input) throws Exception{

FileInputStream fis = new FileInputStream(input);

//FileOutputStream fos = new FileOutputStream(output);

int kl = fis.available();

byte[] kb = new byte[kl];

fis.read(kb);

fis.close();

MessageDigest m=MessageDigest.getInstance("MD5");
m.update(kb,0,kb.length); // hashing

String hashKey=new BigInteger(1,m.digest()).toString(300);

System.out.println("MD5 hash value: "+hashKey);

return hashKey;

Server.java
package network;

import java.net.*;

import java.security.*;

import javax.net.ssl.*;

import javax.crypto.*;

import javax.crypto.spec.*;

import java.security.spec.*;

import java.io.*;

import java.util.Scanner;

import java.math.*;

import java.security.cert.Certificate;

import java.security.cert.X509Certificate;

import javax.net.ssl.SSLSession;

import javax.net.ssl.SSLSocket;

import javax.net.ssl.SSLSocketFactory;

public class Server {


public static void main(String[] args) throws Exception {

Scanner input = new Scanner(System.in);

int filesize=6022386; // filesize temporary hardcoded

int current = 0;

String inputFile = null;

String algorithm = "RSA"; // RSA, DSA

boolean quit = false;

String ksName = "tuananh.jks";

char ksPass[] = "123456".toCharArray();

char ctPass[] = "654321".toCharArray();

//retrieve certificate key store and load certificate for SSL connectiion

KeyStore ks = KeyStore.getInstance("JKS");

ks.load(new FileInputStream(ksName), ksPass);

KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");

kmf.init(ks, ctPass);

SSLContext sc = SSLContext.getInstance("TLS");

KeyManager[] keyManagers = kmf.getKeyManagers();

sc.init(keyManagers, null, null);

//create SSL Socket

SSLServerSocketFactory ssf = sc.getServerSocketFactory();

SSLServerSocket ss = (SSLServerSocket) ssf.createServerSocket(8888);

SSLSocket s = (SSLSocket) ss.accept();


//s.startHandshake();

SSLSession session = ((SSLSocket) s).getSession();

Certificate[] cchain2 = session.getLocalCertificates();

for (int i = 0; i < cchain2.length; i++) {

System.out.println(((X509Certificate) cchain2[i]).getSubjectDN());

System.out.println("Cipher is " + session.getCipherSuite());

CipherGenerator cp = new CipherGenerator();

InputStream is = s.getInputStream();

OutputStream os = s.getOutputStream();

BufferedReader r = new BufferedReader(new InputStreamReader(s.getInputStream()));

BufferedWriter w = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));

//Option:

System.out.println("Please sellect the following option: (0. For exit!)");

System.out.println("1. Retreive the public key from the client and encrypt a document file");

System.out.println("2. Send the encrypted document to client");

System.out.println("3. Send the hash value to client");

System.out.print("Your choice: ");

String temp = input.nextLine();

int choice = Integer.parseInt(temp);

switch (choice) {
case 0:

quit = true;

break;

case 1:

//receieve public key file

receiveFile(filesize, current, is, cp);

//encrypt document using public key

Key ke = cp.readKey(algorithm, "encrypt", "Keyfile-copy.publ");

inputFile = selectFile();

cp.cipherGenerator(algorithm, "encrypt", ke, inputFile, "encrypted.txt");

break;

case 2:

sendEFile(os);

break;

case 3:

String file = selectFile();

sendHash(file, w, cp);

break;

os.close();

s.close();

public static void sendHash(String file, BufferedWriter w, CipherGenerator cp){

try{
String hashVal = cp.md5(file);

w.write(hashVal);

w.flush();

}catch(Exception e) {

System.out.println("Exception: "+e);

public static String retreiveHash(BufferedReader r) throws Exception{

String hash;

hash = r.readLine();

return hash;

public static String selectFile(){

Scanner input = new Scanner(System.in);

System.out.println("Please put your document to working directory and type it name");

String enFile = input.nextLine();

return enFile;

public static void receiveFile( int filesize, int current, InputStream is, CipherGenerator cp){

try{

// receive file

byte [] mybytearray = new byte [filesize];

FileOutputStream fos = new FileOutputStream("Keyfile-copy.publ");

BufferedOutputStream bos = new BufferedOutputStream(fos);

int bytesRead = is.read(mybytearray,0,mybytearray.length);


current = bytesRead;

do {

bytesRead = is.read(mybytearray, current, (mybytearray.length-current));

if(bytesRead >= 0) current += bytesRead;

} while(bytesRead > -1);

bos.write(mybytearray, 0 , current);

bos.flush();

bos.close();

fos.close();

}catch(Exception e) {

System.out.println("Exception: "+e);

return;

public static void sendEFile(OutputStream os){

String input = "encrypted.txt";

try{

//send file

File myFile = new File (input);

byte [] mybytearray = new byte [(int)myFile.length()];

FileInputStream fis = new FileInputStream(myFile);

BufferedInputStream bis = new BufferedInputStream(fis);

bis.read(mybytearray,0,mybytearray.length);

System.out.println("Sending...");

os.write(mybytearray,0,mybytearray.length);

os.flush();
}catch(Exception e) {

System.out.println("Exception: "+e);

Client.java
/*

* To change this template, choose Tools | Templates

* and open the template in the editor.

*/

package network;

import java.net.*;

import java.security.*;

import javax.net.ssl.*;

import javax.crypto.*;

import javax.crypto.spec.*;

import java.security.spec.*;

import java.io.*;

import java.util.Scanner;

import java.math.*;

import java.security.cert.Certificate;

import java.security.cert.X509Certificate;

import javax.net.ssl.SSLSession;

import javax.net.ssl.SSLSocket;

import javax.net.ssl.SSLSocketFactory;
public class Client {

public static void main(String[] args) throws Exception {

Scanner input = new Scanner(System.in);

int filesize=6022386; // filesize temporary hardcoded

int current = 0;

String inputFile = null;

String outputFile = "decrypted.txt";

String algorithm = "RSA"; // RSA, DSA

boolean quit = false;

//retrieve certificate key store and load certificate for SSL connectiion

String ksName = "tuananh2.jks";

char ksPass[] = "123456".toCharArray();

char ctPass[] = "654321".toCharArray();

KeyStore keystore = KeyStore.getInstance("JKS");

keystore.load(new FileInputStream(ksName), ksPass);

TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");

tmf.init(keystore);

//Create SSL Socket

SSLContext context = SSLContext.getInstance("TLS");

TrustManager[] trustManagers = tmf.getTrustManagers();

context.init(null, trustManagers, null);

SSLSocketFactory sf = context.getSocketFactory();

SSLSocket s = (SSLSocket)sf.createSocket("localhost", 8888);

//s.startHandshake();
SSLSession session = ((SSLSocket) s).getSession();

Certificate[] cchain = session.getPeerCertificates();

System.out.println("The Certificates used by peer");

for (int i = 0; i < cchain.length; i++) {

System.out.println(((X509Certificate) cchain[i]).getSubjectDN());

System.out.println("Cipher is " + session.getCipherSuite());

CipherGenerator cp = new CipherGenerator();

InputStream is = s.getInputStream();

OutputStream os = s.getOutputStream();

BufferedReader r = new BufferedReader(new InputStreamReader(s.getInputStream()));

BufferedWriter w = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));

//Option:

System.out.println("Please sellect the following option:");

System.out.println("1. Send the public key file to server");

System.out.println("2. Retreive and decrypt the encrypted document");

System.out.println("3. Perform hash check of file transfer");

System.out.print("Your choice: ");

String temp = input.nextLine();


int choice = Integer.parseInt(temp);

switch (choice) {

case 1:

//send public key file

String keyfile = selectPublicKey();

sendKey(keyfile, os, cp);

break;

case 2:

//receieve encrypted file

receiveFile(filesize, current, is);

//decrypt document using pprivate key

Key ke = cp.readKey(algorithm, "decrypt", "Keyfile.pri");

inputFile = "encrypted.txt";

cp.cipherGenerator(algorithm, "decrypt", ke, inputFile, outputFile);

break;

case 3:

String originalHash = retreiveHash(r);

String currentHash = cp.md5(outputFile);

hashCheck(originalHash, currentHash);

break;

os.close();

s.close();

}
public static void hashCheck(String originalHash, String currentHash){

if (originalHash.equals(currentHash)){

System.out.println("Hash check passed. The file transfer have data integrity");

else{

System.out.println("Hash check failed. The file transfer have problem!");

public static String retreiveHash(BufferedReader r) throws Exception{

String hash;

hash = r.readLine();

return hash;

public static void sendHash(String keyfile, BufferedWriter w, CipherGenerator cp){

try{

String hashVal = cp.md5(keyfile);

w.write(hashVal);

w.flush();

}catch(Exception e) {

System.out.println("Exception: "+e);

public static String selectFile(){

Scanner input = new Scanner(System.in);


System.out.println("Please put your document to working directory and type it name");

String sendFile = input.nextLine();

return sendFile;

public static String selectPublicKey(){

Scanner input = new Scanner(System.in);

System.out.println("Please put your public key to working directory and type it name");

String sendFile = input.nextLine();

return sendFile;

public static void sendKey(String input, OutputStream os, CipherGenerator cp){

//String input = selectPublicKey();

try{

//send public file

File myFile = new File (input);

byte [] mybytearray = new byte [(int)myFile.length()];

FileInputStream fis = new FileInputStream(myFile);

BufferedInputStream bis = new BufferedInputStream(fis);

bis.read(mybytearray,0,mybytearray.length);

//OutputStream os = s.getOutputStream();

System.out.println("Sending...");

os.write(mybytearray,0,mybytearray.length);

os.flush();

}catch(Exception e) {
System.out.println("Exception: "+e);

public static void receiveFile( int filesize, int current, InputStream is){

try{

// receive file

byte [] mybytearray = new byte [filesize];

FileOutputStream fos = new FileOutputStream("encrypted.txt");

BufferedOutputStream bos = new BufferedOutputStream(fos);

int bytesRead = is.read(mybytearray,0,mybytearray.length);

current = bytesRead;

do {

bytesRead = is.read(mybytearray, current, (mybytearray.length-current));

if(bytesRead >= 0) current += bytesRead;

} while(bytesRead > -1);

bos.write(mybytearray, 0 , current);

bos.flush();

bos.close();

}catch(Exception e) {

System.out.println("Exception: "+e);

return;

}
Reference
Java Tool Tutorials © 2006 Dr. Herong Yang, access: 10/2010, http://www.herongyang.com/jtool/

Sun SSL Socket tutorial, access: 10/2010, http://www.java2s.com/Tutorial/Java/0490__Security/

Secure Sockets Layer (SSL), access: 10/2010, http://docstore.mik.ua/orelly/java-


ent/servlet/ch08_03.htm

Potrebbero piacerti anche