hi,

This dis
I have executed the following for verification of Digital Signature from client and server

i have executed below 2 programs Signature AuthenticationServer .java and SignatureAuthenticationClient.java and also created, extracted public and private key through OpenSLL . now when i execute the program and give a encrypted file it is not accepting it .How to proceed please give me sugesstion

import java.io.*;
import java.net.*;
import java.util.*;
import java.security.*;
import java.security.spec.*;

/**
* SignatureAuthenticationServer
*
* This class performs authentication using digital signature.
* It opens a server socket and waits for connections from
* clients.
*/
public class SignatureAuthenticationServer extends Thread {

private static final int PORT = 8001;

private Socket mSocket;
private PublicKey mPublicKey;

public SignatureAuthenticationServer (Socket socket, PublicKey publicKey) {
mSocket = socket;
mPublicKey = publicKey;
this.start();
}

public void run() {
try {
/**
* This is an array that will be passed
* to the client for signing. It consists
* of an 8-byte timestamp followed by a
* 16-byte random number.
*/
byte[] dataToBeSigned;

// Get our input and output streams from the socket
DataInputStream inputFromClient = new
DataInputStream(mSocket.getInputStream());
DataOutputStream outputToClient = new
DataOutputStream(mSocket.getOutputStream());

// Create a timestamp and write it to an array
long timestamp = System.currentTimeMillis();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
DataOutputStream dos = new DataOutputStream(baos);
dos.writeLong(timestamp);

// Create a random value
byte[] randomValue = new byte[16];
SecureRandom random = new SecureRandom();
random.nextBytes(randomValue);

baos.write(randomValue);

dataToBeSigned = baos.toByteArray();

// Send that array, length first so the client knows
// how much data to sign
outputToClient.writeInt(dataToBeSigned.length);
outputToClient.write(dataToBeSigned);
outputToClient.flush();

// Now read in the length of the signature,
// followed by the signature
byte[] signatureBytes = new byte[inputFromClient.readInt()];
inputFromClient.readFully(signatureBytes);

// Now we need to validate the signature
Signature signature = Signature.getInstance("MD5WithRSA");
signature.initVerify(mPublicKey);
signature.update(dataToBeSigned);
boolean authorized = false;
try {
authorized = signature.verify(signatureBytes);
} catch (SignatureException se) {
// In case the signature is padded incorrectly
// this can happen if the client is using the wrong key.
}

outputToClient.writeBoolean(authorized);

if (authorized) {
System.out.println("Client was authorized.\n");
} else {
System.out.println("Access denied.\n");
}
} catch (Exception e) {
System.err.println("Exception: ");
e.printStackTrace();
}
}

/**
* Waits on a port and creates a new SignatureAuthenticationServer
* for each request.
*/
public static void main (String[] args) throws Exception {

// Begin by asking for the public key's filename
BufferedReader in = new BufferedReader
(new InputStreamReader(System.in));
System.out.print("Public Key of client: ");
String publicKeyFilename = in.readLine();

PublicKey publicKey = readPublicKey(publicKeyFilename);

// Now initialize SecureRandom, so that future requests will be fast
System.out.println("Initializing SecureRandom...");
SecureRandom random = new SecureRandom();
byte[] randomBytes = new byte[20];
random.nextBytes(randomBytes);

// Open up a port and create a new server to handle
// each request as it comes in.
ServerSocket ss = new ServerSocket(PORT);
System.out.println("Listening on port "+PORT);

while (true) {
SignatureAuthenticationServer sas =
new SignatureAuthenticationServer
(ss.accept(), publicKey);
}
}

/**
* Read a public key from the file system.
*/
private static PublicKey readPublicKey(String filename) throws Exception {

FileInputStream fis = new FileInputStream(filename);
ByteArrayOutputStream baos = new ByteArrayOutputStream();

int theByte = 0;
while ((theByte = fis.read()) != -1)
{
baos.write(theByte);
}
fis.close();

byte[] keyBytes = baos.toByteArray();
baos.close();

// Turn the encoded key into a real RSA public key.
// Public keys are encoded in X.509.
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PublicKey publicKey = keyFactory.generatePublic(keySpec);
return publicKey;
}
}
-----------------------------------------------------------------------------------------
SignatureAuthenticationClient.java

import java.io.*;
import java.net.*;
import java.security.*;
import java.security.spec.*;
import javax.crypto.*;
import javax.crypto.spec.*;

/**
* SignatureAuthenticationClient
*
* This class attaches to a SignatureAuthenticationServer
* and uses a digital signature to authentitate itself.
*/
public class SignatureAuthenticationClient {

private static final int PORT = 8001;

private static final int MD5_ITERATIONS = 1000;

/**
* First arg is hostname
*/
public static void main (String[] args) throws Exception {
if (args.length != 1) {
System.err.println("Usage: java AuthenticationClient hostname");
System.exit(1);
}

String hostname = args[0];
// Begin by asking for the private key's filename
BufferedReader in = new BufferedReader
(new InputStreamReader(System.in));
System.out.print("Private Key: ");
String privateKeyFilename = in.readLine();
System.out.print("Password: ");
String password = in.readLine();

// Get the private key
PrivateKey privateKey = getPrivateKey
(privateKeyFilename, password.toCharArray());

System.out.println("\nOpening a connection...");
// Open up a connection
Socket socket = new Socket(hostname, PORT);

DataInputStream inputFromServer = new
DataInputStream(socket.getInputStream());
DataOutputStream outputToServer = new
DataOutputStream(socket.getOutputStream());

// Receive byte array to sign
byte[] dataToBeSigned = new byte[inputFromServer.readInt()];
inputFromServer.readFully(dataToBeSigned);

// Now sign it
Signature signature = Signature.getInstance("MD5WithRSA");
signature.initSign(privateKey);
signature.update(dataToBeSigned);
byte[] signatureBytes = signature.sign();

// Write out the signature bytes
outputToServer.writeInt(signatureBytes.length);
outputToServer.write(signatureBytes);
outputToServer.flush();

boolean verified = inputFromServer.readBoolean();

if (verified) {
System.out.println("We were authenticated.");
} else {
System.out.println("Permission denied.");
}
}

private static PrivateKey getPrivateKey(
String privateKeyFilename, char[] password)
throws Exception {

// Load the private key bytes
FileInputStream fis = new FileInputStream(privateKeyFilename);
ByteArrayOutputStream baos = new ByteArrayOutputStream();

int theByte = 0;
while ((theByte = fis.read()) != -1)
{
baos.write(theByte);
}
fis.close();

byte[] keyBytes = baos.toByteArray();
baos.close();

keyBytes = passwordDecrypt(password, keyBytes);

// Turn the encoded key into a real RSA private key.
// Private keys are encoded in PKCS#8.
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PrivateKey privateKey = keyFactory.generatePrivate(keySpec);
return privateKey;
}

private static byte[] passwordDecrypt(
char[] password, byte[] ciphertext)
throws Exception {

// Read in the salt.
byte[] salt = new byte[8];
ByteArrayInputStream bais = new ByteArrayInputStream(ciphertext);
bais.read(salt,0,8);

// The remaining bytes are the actual ciphertext.
byte[] remainingCiphertext = new byte[ciphertext.length-8];
bais.read(remainingCiphertext,0,ciphertext.length-8);

// Create a PBE cipher to decrypt the byte array.
PBEKeySpec keySpec = new PBEKeySpec(password);
SecretKeyFactory keyFactory =
SecretKeyFactory.getInstance("PBEWithSHAAndTwofish-CBC");
SecretKey key = keyFactory.generateSecret(keySpec);
PBEParameterSpec paramSpec = new PBEParameterSpec
(salt, MD5_ITERATIONS);
Cipher cipher = Cipher.getInstance("PBEWithSHAAndTwofish-CBC");

// Perform the actual decryption.
cipher.init(Cipher.DECRYPT_MODE, key, paramSpec);
return cipher.doFinal(remainingCiphertext);
}
}