Secure Chat line using RSA and RMI
* Project Description
The project program allows the multiple clients to talk to each other
by using a Java applet on the network. The program consists of one server
and serveral clients. Each client registers to the server and invokes the
remote object in the server to send its message and the server invokes
the methods in clients to broadcast the message a client has sent to other
clients. Each client is also able to send drawings to other clients. Every
message (text and drawing ) being transfered is encrypted.
* Web technology used
The RMI is used for remote object invocation. To secure the chat line,
RSA is used to encrypt the message before it is sent or recieved.
- RMI
RMI enables the programmer to create distributed Java-to-Java applications,
in which the methods of remote Java objects can be invoked from other Java
virtual machines, possibly on different hosts. A Java program can make
a call on a remote object once it obtains a reference to the remote object,
either by looking up the remote object in the bootstrap-naming service
provided by RMI, or by receiving the reference as an argument or a return
value. A client can call a remote object in a server, and that server can
also be a client of other remote objects. RMI uses Object Serialization
to marshal and unmarshal parameters and does not turncate types, supporting
true object-oriented polymorphism.
- RSA
RSA stands for inventors : Rivest Shamir and Adleman. The idea is take
a number n = p * q, where p and q are primes. Choose a suitable number
e. Public key is < e,n > and basic encryption algorithm takes message
m to be encrypted and forms c = m ^ e mod (n). The decryption involves
private key d which is found so that d * e = 1 mod ((p-1)(q-1)). Then m
= c ^ d mod (n). As factorization is computationally infeasible, this encryption
cannot be broken.
- Architecture
The server runs in one host. Clients run in the same or other hosts.
When server starts, server creates the registry, creates an instance of
the server object and bind the server object with the URL address(registry).
Every client has other clients public key but keeps its own secret key
as private.
When a client starts, it finds the server object and gets a reference
to the server object. A client calls the "connect" method in the server
object, and passes its reference to the server object. Server object in
retunrs calls the method in the client object so that client can update
its user list, and others public keys. The client calls the login method
in the server object to update other clients' user list. When a client
sends a text to other clients, first of all, a client encrypt the message
using other clients' public keys. Then send the encrypted messages to the
server and the server sends the messages to other clients. Other clients
decrypt the message using their own secret keys. Drawing information is
sent to other clients in a similar way as sending the text.
- Invoking procedure for the application.
1. Start RMI server ( RMI server creates the registry in the code)
java -Djava.rmi.server.codebase=http://osprey7.npac.syr.edu:3768/cps616spring98-docs/cp98iya Chat ChatServer &
2. Start applet
appletviewer http://osprey7.npac.syr.edu:3768/cps616spring98-docs/cp98iya/Chat/rmi-chat.html
- Reference :
- Discover problem :
The following routine which calculates the modular arithematic
of the big number gave us the problem. Basically the following routine
does the following modular arithematic , M^D mod N. We do this in a way
so that we do not need to mod the big numbers. We incrementally mod the
numbers. First, we thought that the problem is in the BigDecimal, but now
we examine the code again, the problems is ours. We convert everything
to double after the modular operation. So although the BigDecimal object
contained the big number, since we converted it to double, it came out
incorrect since double overflowed. I have highlighted the code that caused
the problem below. The solution to this would be to use only BigDecimal
for entire program. If I go this way, I do not have to change to the encryption
and decryption parts, but I do have to change the routine which packs the
characters into the numbers and vice versa. For now, the program works
correctly within the type long precision.
long descript(long M, long d, long n)
{
int nbits = (int)(Math.ceil(Math.log(d)/ Math.log(2)));
long OM =M;
long UM=M;
// int quot;
BigDecimal bdn = new BigDecimal( (double)n);
BigDecimal bdm = new BigDecimal( (double)UM);
for ( int i=nbits-2; i>=0 ; i--)
{
if ( ( (d >> i) % 2 ) == 0 )
{
/* quot = (int) ( (double)(M*M) / (double) n );
M = (M*M) - (quot*n);
*/
BigDecimal bdc = bdm.multiply( bdm );
BigDecimal quot = bdc.divide( bdn,BigDecimal.ROUND_DOWN );
bdm = bdc.subtract( quot.multiply(bdn)) ;
}
else
{
/*
quot = (int) ( (double)(M*M*OM) / (double)n );
M = (M*M*OM) - (quot*n);
*/
BigDecimal bdc = bdm.multiply( bdm );
bdc = bdc.multiply( new BigDecimal( (double)OM) );
BigDecimal quot = bdc.divide( bdn,BigDecimal.ROUND_DOWN );
bdm = bdc.subtract( quot.multiply(bdn)) ;
}
}
/* !!!!! problem area */
/*********************************/
M = (long)bdm.doubleValue() ;
/*********************************/
return M;
}
- Source code :
ChatApplet.java
ChatAppletInterface.java
ChatServer.java
ChatServerInterface.java
RSA.java