Some notes related to this assignment from last year.
Double Password Authentication
Few things to keep in mind in this exercise (mainly with regards to DataInputStream/DataOutputStream class:
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 |
MessageDigest.isEqual(recomputedDigest, receivedDigest);
ElGamal Signature
Keys
Create a random prime number p
Choose g and d - both less than p
Calculate y = g^d mod p
Private key is d, public key is (y, g, p)
Signing message m
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) mod p] mod p"
Some issues
BigInteger pOne = BigInteger.valueOf(1);
BigInteger pMinusOne = p.substract(pOne) // where p is the random number
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
Key and KeyGenerator
- check 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
ObjectOutputStream outSocket = new ObjectOutputStream(s.getOutputStream());
2. Cipher - Encrypting and Decrypting and then outputting the digest
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
Note that in the documentation at the URL provided to you sey 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.