// Key client // // The constructor connects to the Key Server to obtain the randomly generated // RSA public key, and initializes a sequence generator. // // login() handles the authentication and transfer of the SecureRandom seed to // the Login server. // // R. Perry, July 1998 import java.io.*; import java.rmi.*; import java.security.*; import cryptix.provider.rsa.*; import cryptix.util.core.Hex; import sequence.Sequence; public class KeyClient { private String server; // server hostname private int port; // server port number private PublicKey pk; // RSA public key private String pk_hex; // public key in hex private Sequence seq; // SecureRandom sequence generator public KeyClient( String server, int port, String service) throws Exception { this.server = server; this.port = port; // connect to Key Server and get public key // String rmi = "rmi://" + server + ":" + port + "/KeyServer"; System.out.println( "KeyClient: contacting " + rmi); Key K = (Key) Naming.lookup( rmi); System.out.println( "KeyClient: getting public key"); pk = K.getKey( service); pk_hex = Hex.toString(pk.getEncoded()); System.out.println( "KeyClient: initializing sequence generator"); seq = new Sequence(); // this call takes some time } public boolean login( String auth) throws Exception { // encrypt login string // System.out.println( "KeyClient: encrypting login string"); Cipher c = Cipher.getInstance( "RSA"); c.initEncrypt( pk); // c.init( Cipher.ENCRYPT, pk); byte[] b_in = new byte[c.getPlaintextBlockSize()]; // byte[] b_in = new byte[c.getBlockSize()]; System.out.println( "KeyClient: BlockSize = " + b_in.length); // need at least 21 bytes at the end for the sequence seed // if( auth.length() > b_in.length - 21) { System.out.println( "KeyClient: auth string is too long."); return false; } byte[] seed = seq.getSeed(); // b_in will be: auth, 0, seed, 0 ... // for( int i = 0, j = 0; i < b_in.length; ++i) if( i < auth.length()) b_in[i] = (byte) auth.charAt(i); else if( i == auth.length()) b_in[i] = 0; else if( j < seed.length) b_in[i] = seed[j++]; else b_in[i] = 0; byte[] b_out = c.crypt(b_in); // byte[] b_out = c.doFinal(b_in); for( int i = 0; i < b_in.length; ++i) // destroy plaintext data b_in[i] = 0; // connect to Login Server // String rmi = "rmi://" + server + ":" + port + "/LoginServer-" + pk_hex; System.out.println( "KeyClient: contacting " + rmi); Login L = (Login) Naming.lookup( rmi); return L.login( b_out); } /* * seqnum: returns the next sequence number */ public long seqnum() { return seq.next(); } /* * getKey: returns the RSA public key as a hex string */ public String getKey() { return pk_hex; } }